
#include <assert.h>

#include <hei_main.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>

#include <filesystem>
#include <fstream>
#include <map>
#include <vector>

namespace fs = std::filesystem;

namespace analyzer
{

//------------------------------------------------------------------------------

void __getChipDataFiles(std::map<libhei::ChipType_t, fs::path>& o_files)
{
    o_files.clear();

    auto directory = "/usr/share/openpower-libhei/";

    for (const auto& entry : fs::directory_iterator(directory))
    {
        auto path = entry.path();

        std::ifstream file{path, std::ios::binary};
        if (!file.good())
        {
            trace::err("Unable to open file: %s", path.string().c_str());
            continue;
        }

        // The first 8-bytes is the file keyword and the next 4-bytes is the
        // chip type.
        libhei::FileKeyword_t keyword;
        libhei::ChipType_t chipType;

        const size_t sz_keyword = sizeof(keyword);
        const size_t sz_chipType = sizeof(chipType);
        const size_t sz_buffer = sz_keyword + sz_chipType;

        // Read the keyword and chip type from the file.
        char buffer[sz_buffer];
        file.read(buffer, sz_buffer);
        if (!file.good())
        {
            trace::err("Unable to read file: %s", path.string().c_str());
            continue;
        }

        // Get the keyword.
        memcpy(&keyword, &buffer[0], sz_keyword);
        keyword = be64toh(keyword);

        // Ensure the keyword value is correct.
        if (libhei::KW_CHIPDATA != keyword)
        {
            trace::err("Invalid chip data file: %s", path.string().c_str());
            continue;
        }

        // Get the chip type.
        memcpy(&chipType, &buffer[sz_keyword], sz_chipType);
        chipType = be32toh(chipType);

        // Trace each legitimate chip data file for debug.
        trace::inf("File found: type=0x%0" PRIx32 " path=%s", chipType,
                   path.string().c_str());

        // So far, so good. Add the entry.
        auto ret = o_files.emplace(chipType, path);
        assert(ret.second); // Should not have duplicate entries
    }
}

//------------------------------------------------------------------------------

void __initialize(const fs::path& i_path)
{
    // Get file size.
    const auto sz_buffer = fs::file_size(i_path);

    // Create a buffer large enough to hold the entire file.
    std::vector<char> buffer(sz_buffer);

    // Open the chip data file.
    std::ifstream file{i_path, std::ios::binary};
    assert(file.good()); // We've opened it once before, so it should open now.

    // Read the entire file into the buffer.
    file.read(buffer.data(), sz_buffer);
    assert(file.good()); // Again, this should be readable.

    // This is not necessary, but it frees up memory before calling the memory
    // intensive initialize() function.
    file.close();

    // Initialize the isolator with this chip data file.
    libhei::initialize(buffer.data(), sz_buffer);
}

//------------------------------------------------------------------------------

void initializeIsolator(std::vector<libhei::Chip>& o_chips)
{
    // Get all of the active chips to be analyzed.
    util::pdbg::getActiveChips(o_chips);

    // Find all of the existing chip data files.
    std::map<libhei::ChipType_t, fs::path> files;
    __getChipDataFiles(files);

    // Keep track of models/levels that have already been initialized.
    std::map<libhei::ChipType_t, unsigned int> initTypes;

    for (const auto& chip : o_chips)
    {
        auto chipType = chip.getType();

        // Mark this chip type as initialized (or will be if it hasn't been).
        auto ret = initTypes.emplace(chipType, 1);
        if (!ret.second)
        {
            // This type has already been initialized. Nothing more to do.
            continue;
        }

        // Get the file for this chip.
        auto itr = files.find(chipType);

        // Ensure a chip data file exist for this chip.
        assert(files.end() != itr);

        // Initialize this chip type.
        __initialize(itr->second);
    }
}

//------------------------------------------------------------------------------

} // namespace analyzer
