#include "editor_impl.hpp"
#include "ipz_parser.hpp"

#include <algorithm>
#include <nlohmann/json.hpp>
#include <vector>

#include <gtest/gtest.h>

using namespace openpower::vpd;
using namespace openpower::vpd::manager::editor;
using namespace openpower::vpd::inventory;
using namespace openpower::vpd::constants;

class vpdManagerEditorTest : public ::testing::Test
{
  protected:
    Binary vpd;

    nlohmann::json jsonFile;

    // map to hold the mapping of location code and inventory path
    inventory::LocationCodeMap fruLocationCode;

  public:
    // constructor
    vpdManagerEditorTest()
    {
        processJson();
    }

    void processJson();
    void readFile(std::string pathToFile);
};

void vpdManagerEditorTest::readFile(std::string pathToFile)
{
    // read the json file and parse it
    std::ifstream vpdFile(pathToFile, std::ios::binary);

    if (!vpdFile)
    {
        throw std::runtime_error("json file not found");
    }

    vpd.assign((std::istreambuf_iterator<char>(vpdFile)),
               std::istreambuf_iterator<char>());
}

void vpdManagerEditorTest::processJson()
{
    // read the json file and parse it
    std::ifstream json("vpd-manager-test/vpd_editor_test.json",
                       std::ios::binary);

    if (!json)
    {
        throw std::runtime_error("json file not found");
    }

    jsonFile = nlohmann::json::parse(json);

    const nlohmann::json& groupFRUS =
        jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
    for (const auto& itemFRUS : groupFRUS.items())
    {
        const std::vector<nlohmann::json>& groupEEPROM =
            itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
        for (const auto& itemEEPROM : groupEEPROM)
        {
            fruLocationCode.emplace(
                itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]["LocationCode"]
                    .get_ref<const nlohmann::json::string_t&>(),
                itemEEPROM["inventoryPath"]
                    .get_ref<const nlohmann::json::string_t&>());
        }
    }
}

TEST_F(vpdManagerEditorTest, InvalidFile)
{
    Binary dataToUodate{'M', 'O', 'D', 'I', 'F', 'Y',
                        'D', 'A', 'T', 'A', 'O', 'K'};

    Binary emptyVpdFile;
    try
    {
        // Invalid kwd name
        EditorImpl edit("VINI", "SN", std::move(emptyVpdFile));
        edit.updateKeyword(dataToUodate);
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(std::string(e.what()), std::string("Invalid File"));
    }
}

TEST_F(vpdManagerEditorTest, InvalidHeader)
{
    Binary dataToUodate{'M', 'O', 'D', 'I', 'F', 'Y',
                        'D', 'A', 'T', 'A', 'O', 'K'};

    readFile("vpd-manager-test/invalidHeaderFile.dat");
    try
    {
        // the path is dummy
        EditorImpl edit("VINI", "SN", std::move(vpd));
        edit.updateKeyword(dataToUodate);
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(std::string(e.what()), std::string("VHDR record not found"));
    }
}

TEST_F(vpdManagerEditorTest, InvalidRecordName)
{
    Binary dataToUodate{'M', 'O', 'D', 'I', 'F', 'Y',
                        'D', 'A', 'T', 'A', 'O', 'K'};

    readFile("vpd-manager-test/vpdFile.dat");

    try
    {
        // Invalid record name "VIN", path is dummy
        EditorImpl edit("VIN", "SN", std::move(vpd));
        edit.updateKeyword(dataToUodate);
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(std::string(e.what()), std::string("Record not found"));
    }
}

TEST_F(vpdManagerEditorTest, InvalidKWdName)
{
    Binary dataToUodate{'M', 'O', 'D', 'I', 'F', 'Y',
                        'D', 'A', 'T', 'A', 'O', 'K'};

    readFile("vpd-manager-test/vpdFile.dat");

    try
    {
        // All valid data
        EditorImpl edit("VINI", "Sn", std::move(vpd));
        edit.updateKeyword(dataToUodate);
    }
    catch (std::runtime_error& e)
    {
        EXPECT_EQ(std::string(e.what()), std::string("Keyword not found"));
    }
}

TEST_F(vpdManagerEditorTest, UpdateKwd_Success)
{
    Binary dataToUodate{'M', 'O', 'D', 'I', 'F', 'Y',
                        'D', 'A', 'T', 'A', 'O', 'K'};

    readFile("vpd-manager-test/vpdFile.dat");

    try
    {
        // All valid data
        EditorImpl edit("VINI", "SN", std::move(vpd));
        edit.updateKeyword(dataToUodate);
    }
    catch (std::runtime_error& e)
    {
        EXPECT_EQ(std::string(e.what()),
                  std::string("Data updated successfully"));
    }
}

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}