/*
 * Copyright 2020 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <gtest/gtest.h>

#include <vector>

#include "sim/proxy_ptr.hh"

using namespace gem5;

struct Access
{
    bool read;
    Addr addr;
    Addr size;

    Access(bool _read, Addr _addr, Addr _size) :
        read(_read), addr(_addr), size(_size)
    {}

    bool
    operator == (const Access &other) const
    {
        return read == other.read &&
               addr == other.addr &&
               size == other.size;
    }

    bool
    operator != (const Access &other) const
    {
        return !(*this == other);
    }
};

using Accesses = std::vector<Access>;

class BackingStore
{
  public:
    std::vector<uint8_t> store;
    Addr base;

    BackingStore(Addr _base, size_t _size) : store(_size, 0), base(_base) {}

    void
    rangeCheck(Addr addr, Addr size)
    {
        panic_if(addr < base || addr + size > base + store.size(),
                 "Range [%#x,%#x) outside of [%#x,%#x).",
                 addr, addr + size, base, base + store.size());
    }

    mutable Accesses accesses;

    ::testing::AssertionResult
    expect_access(size_t idx, const Access &other) const
    {
        if (idx >= accesses.size()) {
            return ::testing::AssertionFailure() << "index " << idx <<
                " out of bounds";
        }

        if (accesses[idx] != other) {
            return ::testing::AssertionFailure() << "access[" << idx <<
                "] was " << accesses[idx] << ", expected " << other;
        }
        return ::testing::AssertionSuccess();
    }

    ::testing::AssertionResult
    expect_accesses(Accesses expected) const
    {
        if (accesses.size() != expected.size()) {
            return ::testing::AssertionFailure() <<
                "Wrong number of accesses, was " << accesses.size() <<
                " expected " << expected.size();
        }

        auto failure = ::testing::AssertionFailure();
        bool success = true;
        if (accesses.size() == expected.size()) {
            for (size_t idx = 0; idx < expected.size(); idx++) {
                auto result = expect_access(idx, expected[idx]);
                if (!result) {
                    failure << result.message();
                    success = false;
                }
            }
        }

        if (!success)
            return failure;
        else
            return ::testing::AssertionSuccess();
    }

    void
    writeBlob(Addr ptr, const void *data, int size)
    {
        rangeCheck(ptr, size);
        accesses.emplace_back(false, ptr, size);
        memcpy(store.data() + (ptr - base), data, size);
    }

    void
    readBlob(Addr ptr, void *data, int size)
    {
        rangeCheck(ptr, size);
        accesses.emplace_back(true, ptr, size);
        memcpy(data, store.data() + (ptr - base), size);
    }
};

::testing::AssertionResult
accessed(const char *expr1, const char *expr2,
         const BackingStore &store, const Accesses &expected)
{
    return store.expect_accesses(expected);
}

#define EXPECT_ACCESSES(store, ...) \
    do { \
        Accesses expected({__VA_ARGS__}); \
        EXPECT_PRED_FORMAT2(accessed, store, expected); \
        store.accesses.clear(); \
    } while (false)

std::ostream &
operator << (std::ostream &os, const Access &access)
{
    ccprintf(os, "%s(%#x, %d)", access.read ? "read" : "write",
            access.addr, access.size);
    return os;
}

class TestProxy
{
  public:
    BackingStore &store;

    TestProxy(BackingStore &_store) : store(_store) {}
    // Sneaky constructor for testing guest_abi integration.
    TestProxy(ThreadContext *tc) : store(*(BackingStore *)tc) {}

    void
    writeBlob(Addr ptr, const void *data, int size)
    {
        store.writeBlob(ptr, data, size);
    }

    void
    readBlob(Addr ptr, void *data, int size)
    {
        store.readBlob(ptr, data, size);
    }
};

template <typename T>
using TestPtr = ProxyPtr<T, TestProxy>;

template <typename T>
using ConstTestPtr = ConstProxyPtr<T, TestProxy>;

TEST(ProxyPtr, Clean)
{
    BackingStore store(0x1000, 0x1000);

    EXPECT_ACCESSES(store);

    {
        ConstTestPtr<uint32_t> test_ptr(0x1100, store);

        EXPECT_ACCESSES(store, { true, test_ptr.addr(), sizeof(uint32_t) });
    }

    EXPECT_ACCESSES(store);

    {
        TestPtr<uint32_t> test_ptr(0x1100, store);

        EXPECT_ACCESSES(store, { true, test_ptr.addr(), sizeof(uint32_t) });
    }

    EXPECT_ACCESSES(store);
}

TEST(ProxyPtr, Dirty)
{
    BackingStore store(0x1000, 0x1100);

    EXPECT_ACCESSES(store);

    {
        TestPtr<uint32_t> test_ptr(0x1100, store);

        *test_ptr = 0xa5a5a5a5;

        EXPECT_ACCESSES(store, { true, test_ptr.addr(), sizeof(uint32_t) });
    }

    EXPECT_ACCESSES(store, { false, 0x1100, sizeof(uint32_t) });
    EXPECT_EQ(store.store[0x100], 0xa5);
    EXPECT_EQ(store.store[0x101], 0xa5);
    EXPECT_EQ(store.store[0x102], 0xa5);
    EXPECT_EQ(store.store[0x103], 0xa5);
}


TEST(ProxyPtr, LoadAndFlush)
{
    BackingStore store(0x1000, 0x1100);

    store.store[0x100] = 0xa5;
    store.store[0x101] = 0xa5;
    store.store[0x102] = 0xa5;
    store.store[0x103] = 0xa5;

    TestPtr<uint32_t> test_ptr(0x1100, store);

    // Check that the backing store is unmodified.
    EXPECT_EQ(store.store[0x100], 0xa5);
    EXPECT_EQ(store.store[0x101], 0xa5);
    EXPECT_EQ(store.store[0x102], 0xa5);
    EXPECT_EQ(store.store[0x103], 0xa5);

    // Change the value in our local buffered copy.
    *test_ptr = 0x5a5a5a5a;

    // Verify that the backing store hasn't been changed.
    EXPECT_EQ(store.store[0x100], 0xa5);
    EXPECT_EQ(store.store[0x101], 0xa5);
    EXPECT_EQ(store.store[0x102], 0xa5);
    EXPECT_EQ(store.store[0x103], 0xa5);

    // Flush out our modifications.
    test_ptr.flush();

    // Verify that they've been written back to the store.
    EXPECT_EQ(store.store[0x100], 0x5a);
    EXPECT_EQ(store.store[0x101], 0x5a);
    EXPECT_EQ(store.store[0x102], 0x5a);
    EXPECT_EQ(store.store[0x103], 0x5a);

    // Update the store and try to flush again.
    store.store[0x100] = 0xaa;
    test_ptr.flush();

    // Verify that no flush happened, since our ptr was "clean".
    EXPECT_EQ(store.store[0x100], 0xaa);

    // Force a flush.
    test_ptr.flush(true);

    // Verify that the flush happened even though the ptr was "clean".
    EXPECT_EQ(store.store[0x100], 0x5a);

    // Update the store.
    store.store[0x100] = 0xa5;
    store.store[0x101] = 0xa5;
    store.store[0x102] = 0xa5;
    store.store[0x103] = 0xa5;

    // Verify that our local copy hasn't changed.
    EXPECT_EQ(*(const uint32_t *)test_ptr, 0x5a5a5a5a);

    // Reload the pointer from the store.
    test_ptr.load();
    EXPECT_EQ(*(const uint32_t *)test_ptr, 0xa5a5a5a5);
}

TEST(ProxyPtr, ConstOperators)
{
    bool is_same;

    BackingStore store(0x1000, 0x1000);

    const Addr addr1 = 0x1100;
    const Addr addr2 = 0x1200;

    using PtrType = uint32_t;

    ConstTestPtr<PtrType> test_ptr1(addr1, store);
    EXPECT_EQ(test_ptr1.addr(), addr1);

    ConstTestPtr<PtrType> test_ptr2(addr2, store);
    EXPECT_EQ(test_ptr2.addr(), addr2);

    // Pointer +/- integer.
    auto next_ptr = test_ptr1 + 2;
    EXPECT_EQ(next_ptr.addr(), addr1 + 2 * sizeof(PtrType));

    auto reverse_next_ptr = 2 + test_ptr1;
    EXPECT_EQ(reverse_next_ptr.addr(), addr1 + 2 * sizeof(PtrType));

    auto prev_ptr = test_ptr1 - 2;
    EXPECT_EQ(prev_ptr.addr(), addr1 - 2 * sizeof(PtrType));

    // Pointer-pointer subtraction.
    auto diff = test_ptr2 - test_ptr1;
    EXPECT_EQ(diff, (addr2 - addr1) / sizeof(PtrType));

    // Assignment.
    ConstTestPtr<PtrType> target(addr2, store);
    EXPECT_EQ(target.addr(), addr2);

    target = test_ptr1;
    EXPECT_EQ(target.addr(), addr1);

    // Conversions.
    EXPECT_TRUE(test_ptr1);
    ConstTestPtr<PtrType> null(0, store);
    EXPECT_FALSE(null);

    EXPECT_NE((const PtrType *)test_ptr1, nullptr);
    EXPECT_EQ((const PtrType *)null, nullptr);

    // Dereferences.
    is_same = std::is_same_v<decltype(*test_ptr1), const PtrType &>;
    EXPECT_TRUE(is_same);

    store.store[0x100] = 0x55;
    store.store[0x101] = 0x55;
    store.store[0x102] = 0x55;
    store.store[0x103] = 0x55;

    // Force an update since we changed the backing store behind our ptrs back.
    test_ptr1.load();

    EXPECT_EQ(*test_ptr1, 0x55555555);

    store.store[0x100] = 0x11;
    store.store[0x101] = 0x22;
    store.store[0x102] = 0x33;
    store.store[0x103] = 0x44;

    struct TestStruct
    {
        uint8_t a;
        uint8_t b;
        uint8_t c;
        uint8_t d;
    };

    ConstTestPtr<TestStruct> struct_ptr(addr1, store);
    EXPECT_EQ(struct_ptr->a, 0x11);
    EXPECT_EQ(struct_ptr->b, 0x22);
    EXPECT_EQ(struct_ptr->c, 0x33);
    EXPECT_EQ(struct_ptr->d, 0x44);

    is_same = std::is_same_v<decltype((struct_ptr->a)), const uint8_t &>;
    EXPECT_TRUE(is_same);
}

TEST(ProxyPtr, NonConstOperators)
{
    bool is_same;

    BackingStore store(0x1000, 0x1000);

    const Addr addr1 = 0x1100;
    const Addr addr2 = 0x1200;

    using PtrType = uint32_t;

    TestPtr<PtrType> test_ptr1(addr1, store);
    EXPECT_EQ(test_ptr1.addr(), addr1);

    TestPtr<PtrType> test_ptr2(addr2, store);
    EXPECT_EQ(test_ptr2.addr(), addr2);

    // Pointer +/- integer.
    auto next_ptr = test_ptr1 + 2;
    EXPECT_EQ(next_ptr.addr(), addr1 + 2 * sizeof(PtrType));

    auto reverse_next_ptr = 2 + test_ptr1;
    EXPECT_EQ(reverse_next_ptr.addr(), addr1 + 2 * sizeof(PtrType));

    auto prev_ptr = test_ptr1 - 2;
    EXPECT_EQ(prev_ptr.addr(), addr1 - 2 * sizeof(PtrType));

    // Pointer-pointer subtraction.
    auto diff = test_ptr2 - test_ptr1;
    EXPECT_EQ(diff, (addr2 - addr1) / sizeof(PtrType));

    // Assignment.
    TestPtr<PtrType> target(addr2, store);
    EXPECT_EQ(target.addr(), addr2);

    target = test_ptr1;
    EXPECT_EQ(target.addr(), addr1);

    // Conversions.
    EXPECT_TRUE(test_ptr1);
    TestPtr<PtrType> null(0, store);
    EXPECT_FALSE(null);

    EXPECT_NE((PtrType *)test_ptr1, nullptr);
    EXPECT_EQ((PtrType *)null, nullptr);
    EXPECT_NE((const PtrType *)test_ptr1, nullptr);
    EXPECT_EQ((const PtrType *)null, nullptr);

    // Dereferences.
    is_same = std::is_same_v<decltype(*test_ptr1), PtrType &>;
    EXPECT_TRUE(is_same);

    // Flush test_ptr1, which has been conservatively marked as dirty.
    test_ptr1.flush();

    store.store[0x100] = 0x55;
    store.store[0x101] = 0x55;
    store.store[0x102] = 0x55;
    store.store[0x103] = 0x55;

    // Force an update since we changed the backing store behind our ptrs back.
    test_ptr1.load();

    EXPECT_EQ(*test_ptr1, 0x55555555);

    store.store[0x100] = 0x11;
    store.store[0x101] = 0x22;
    store.store[0x102] = 0x33;
    store.store[0x103] = 0x44;

    struct TestStruct
    {
        uint8_t a;
        uint8_t b;
        uint8_t c;
        uint8_t d;
    };

    TestPtr<TestStruct> struct_ptr(addr1, store);
    EXPECT_EQ(struct_ptr->a, 0x11);
    EXPECT_EQ(struct_ptr->b, 0x22);
    EXPECT_EQ(struct_ptr->c, 0x33);
    EXPECT_EQ(struct_ptr->d, 0x44);

    is_same = std::is_same_v<decltype((struct_ptr->a)), uint8_t &>;
    EXPECT_TRUE(is_same);
}

struct TestABI
{
    using UintPtr = uint64_t;
    using State = int;
};

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
namespace guest_abi
{

template <>
struct Argument<TestABI, Addr>
{
    static Addr
    get(ThreadContext *tc, typename TestABI::State &state)
    {
        return 0x1000;
    }
};

} // namespace guest_abi
} // namespace gem5

bool abiCalled = false;
bool abiCalledConst = false;

void
abiTestFunc(ThreadContext *tc, TestPtr<uint8_t> ptr)
{
    abiCalled = true;
    EXPECT_EQ(ptr.addr(), 0x1000);
}

void
abiTestFuncConst(ThreadContext *tc, ConstTestPtr<uint8_t> ptr)
{
    abiCalledConst = true;
    EXPECT_EQ(ptr.addr(), 0x1000);
}

TEST(ProxyPtrTest, GuestABI)
{
    BackingStore store(0x1000, 0x1000);

    EXPECT_FALSE(abiCalled);
    EXPECT_FALSE(abiCalledConst);

    invokeSimcall<TestABI>((ThreadContext *)&store, abiTestFunc);

    EXPECT_TRUE(abiCalled);
    EXPECT_FALSE(abiCalledConst);

    invokeSimcall<TestABI>((ThreadContext *)&store, abiTestFuncConst);

    EXPECT_TRUE(abiCalled);
    EXPECT_TRUE(abiCalledConst);
}
