/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "interpreter.h"
#include "test_utilities.h"

#include <gtest/gtest.h>

#include <memory>
#include <vector>

namespace gapir {
namespace test {
namespace {

const uint32_t MEMORY_SIZE = 4096;
const uint32_t STACK_SIZE = 128;

template <typename T>
struct CheckTopOfStack {
    T expected_;
    bool operator()(Stack* stack, bool) {
        EXPECT_EQ(expected_, stack->pop<T>());
        return true;
    }
};

class InterpreterTest : public ::testing::Test {
protected:
    virtual void SetUp() {
        std::vector<uint32_t> memorySizes = {MEMORY_SIZE};
        mMemoryManager.reset(new MemoryManager(memorySizes));
        mInterpreter.reset(new Interpreter(mMemoryManager.get(), STACK_SIZE));
    }

    std::unique_ptr<MemoryManager> mMemoryManager;
    std::unique_ptr<Interpreter> mInterpreter;
};
}  // anonymous namespace

TEST_F(InterpreterTest, PushIUint8) {
    mInterpreter->registerFunction(0, CheckTopOfStack<uint8_t>{210});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint8, 210),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, PushIInt16Minus1) {
    mInterpreter->registerFunction(0, CheckTopOfStack<int16_t>{-1});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Int16, 0xffff),  // -1
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, PushIInt32Minus1) {
    mInterpreter->registerFunction(0, CheckTopOfStack<int32_t>{-1});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Int32, 0xfffff),  // -1
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, PushIFloat1) {
    mInterpreter->registerFunction(0, CheckTopOfStack<float>{1.0f});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Float, 0x7f),  // 1.0 exp
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, PushIDouble1) {
    mInterpreter->registerFunction(0, CheckTopOfStack<double>{1.0});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Double, 0x3ff),  // 1.0 exp
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, LoadC) {
    mMemoryManager->setReplayDataSize(10);
    uint8_t constantMemory[7] = {0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a};
    uint8_t* constantBaseAddress = static_cast<uint8_t*>(mMemoryManager->getReplayAddress()) + 2;
    memcpy(constantBaseAddress, &constantMemory, sizeof(constantMemory));
    mMemoryManager->setConstantMemory({constantBaseAddress, sizeof(constantMemory)});

    mInterpreter->registerFunction(0, CheckTopOfStack<uint16_t>{0x7856});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::LOAD_C, BaseType::Uint16, 4),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, LoadV) {
    *static_cast<int32_t*>(mMemoryManager->volatileToAbsolute(784)) = -987654321;
    mInterpreter->registerFunction(0, CheckTopOfStack<int32_t>{-987654321});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::LOAD_V, BaseType::Int32, 784),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, LoadConstantAddress) {
    mMemoryManager->setReplayDataSize(10);
    uint8_t constantMemory[7] = {0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a};
    uint8_t* constantBaseAddress = static_cast<uint8_t*>(mMemoryManager->getReplayAddress()) + 2;
    memcpy(constantBaseAddress, &constantMemory, 7);
    mMemoryManager->setConstantMemory({constantBaseAddress, 7});

    mInterpreter->registerFunction(0, CheckTopOfStack<uint16_t>{0x7856});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::ConstantPointer, 4),
            instruction(Interpreter::InstructionCode::LOAD, BaseType::Uint16, 0),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, LoadVolatileAddress) {
    *static_cast<int32_t*>(mMemoryManager->volatileToAbsolute(784)) = -987654321;
    mInterpreter->registerFunction(0, CheckTopOfStack<int32_t>{-987654321});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::VolatilePointer, 784),
            instruction(Interpreter::InstructionCode::LOAD, BaseType::Int32, 0),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, Pop) {
    mInterpreter->registerFunction(0, CheckTopOfStack<uint32_t>{123456});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint32, 123456),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint16, 987),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Int8, -123),
            instruction(Interpreter::InstructionCode::POP, 2),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, StoreV) {
    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint32, 987654),
            instruction(Interpreter::InstructionCode::STORE_V, 124)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);

    EXPECT_EQ(987654, *static_cast<uint32_t*>(mMemoryManager->volatileToAbsolute(124)));
}

TEST_F(InterpreterTest, Store) {
    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint32, 987654),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::VolatilePointer, 260),
            instruction(Interpreter::InstructionCode::STORE, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);

    EXPECT_EQ(987654, *static_cast<uint32_t*>(mMemoryManager->volatileToAbsolute(260)));
}

TEST_F(InterpreterTest, Copy) {
    mMemoryManager->setReplayDataSize(20);
    uint8_t constantMemory[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    uint8_t* constantBaseAddress = static_cast<uint8_t*>(mMemoryManager->getReplayAddress()) + 2;
    memcpy(constantBaseAddress, &constantMemory, 10);
    mMemoryManager->setConstantMemory({constantBaseAddress, 10});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::ConstantPointer, 5),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::VolatilePointer, 987),
            instruction(Interpreter::InstructionCode::COPY, 3)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);

    EXPECT_EQ(5, *static_cast<uint8_t*>(mMemoryManager->volatileToAbsolute(987)));
    EXPECT_EQ(6, *static_cast<uint8_t*>(mMemoryManager->volatileToAbsolute(988)));
    EXPECT_EQ(7, *static_cast<uint8_t*>(mMemoryManager->volatileToAbsolute(989)));
}

TEST_F(InterpreterTest, Clone) {
    mInterpreter->registerFunction(0, CheckTopOfStack<uint32_t>{123456});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint32, 123456),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Uint16, 987),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Int8, -123),
            instruction(Interpreter::InstructionCode::CLONE, 2),
            instruction(Interpreter::InstructionCode::CALL, 0),
            instruction(Interpreter::InstructionCode::POP, 2),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, ExtendInt32) {
    mInterpreter->registerFunction(0, CheckTopOfStack<int32_t>{0x76543210});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Int32, 0x1d),
            instruction(Interpreter::InstructionCode::EXTEND, 0x2543210),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, ExtendFloat) {
    mInterpreter->registerFunction(0, CheckTopOfStack<float>{1.1f});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Float, 0x7f),
            instruction(Interpreter::InstructionCode::EXTEND, 0x8ccccd),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, ExtendDouble) {
    mInterpreter->registerFunction(0, CheckTopOfStack<double>{1.4});

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::Double, 0x3ff),
            instruction(Interpreter::InstructionCode::EXTEND, 0x1999999),
            instruction(Interpreter::InstructionCode::EXTEND, 0x2666666),
            instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
}

TEST_F(InterpreterTest, Strcpy) {
    mMemoryManager->setReplayDataSize(20);
    const char* constantMemory = "abc";
    uint8_t* constantBaseAddress = static_cast<uint8_t*>(mMemoryManager->getReplayAddress());
    memcpy(constantBaseAddress, constantMemory, 4);
    mMemoryManager->setConstantMemory({constantBaseAddress, 4});

    uint8_t* volatileMemory = static_cast<uint8_t*>(mMemoryManager->volatileToAbsolute(100));

    memset(volatileMemory, 'x', 5);

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::ConstantPointer, 0),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::VolatilePointer, 100),
            instruction(Interpreter::InstructionCode::STRCPY, 10)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);

    EXPECT_EQ('a', volatileMemory[0]);
    EXPECT_EQ('b', volatileMemory[1]);
    EXPECT_EQ('c', volatileMemory[2]);
    EXPECT_EQ(0x0, volatileMemory[3]);
    EXPECT_EQ(0x0, volatileMemory[4]);
}

TEST_F(InterpreterTest, StrcpyShortBuffer) {
    mMemoryManager->setReplayDataSize(20);
    const char* constantMemory = "abcdef";
    uint8_t* constantBaseAddress = static_cast<uint8_t*>(mMemoryManager->getReplayAddress());
    memcpy(constantBaseAddress, constantMemory, 7);
    mMemoryManager->setConstantMemory({constantBaseAddress, 7});

    uint8_t* volatileMemory = static_cast<uint8_t*>(mMemoryManager->volatileToAbsolute(100));

    memset(volatileMemory, 'x', 8);

    std::vector<uint32_t> instructions{
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::ConstantPointer, 0),
            instruction(Interpreter::InstructionCode::PUSH_I, BaseType::VolatilePointer, 100),
            instruction(Interpreter::InstructionCode::STRCPY, 5)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);

    EXPECT_EQ('a', volatileMemory[0]);
    EXPECT_EQ('b', volatileMemory[1]);
    EXPECT_EQ('c', volatileMemory[2]);
    EXPECT_EQ('d', volatileMemory[3]);
    EXPECT_EQ(0x0, volatileMemory[4]);
    EXPECT_EQ('x', volatileMemory[5]);
}

TEST_F(InterpreterTest, Post) {
    uint32_t callCount = 0;
    auto post = [&callCount](Stack*, bool) {
        ++callCount;
        return true;
    };

    mInterpreter->registerFunction(Interpreter::POST_FUNCTION_ID, post);

    std::vector<uint32_t> instructions{instruction(Interpreter::InstructionCode::POST)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
    EXPECT_EQ(1, callCount);
}

TEST_F(InterpreterTest, Resource) {
    uint32_t callCount = 0;
    auto resource = [&callCount](Stack* stack, bool) {
        ++callCount;
        return true;
    };

    mInterpreter->registerFunction(0, CheckTopOfStack<uint32_t>{123});
    mInterpreter->registerFunction(Interpreter::RESOURCE_FUNCTION_ID, resource);

    std::vector<uint32_t> instructions{instruction(Interpreter::InstructionCode::RESOURCE, 123),
                                       instruction(Interpreter::InstructionCode::CALL, 0)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_TRUE(res);
    EXPECT_EQ(1, callCount);
}

TEST_F(InterpreterTest, InvalidOpcode) {
    std::vector<uint32_t> instructions{63U << 26};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_FALSE(res);
}

TEST_F(InterpreterTest, InvalidFunctionId) {
    std::vector<uint32_t> instructions{instruction(Interpreter::InstructionCode::CALL, 0xffff)};
    bool res = mInterpreter->run({&instructions.front(), instructions.size()});
    EXPECT_FALSE(res);
}

}  // namespace test
}  // namespace gapir
