#include <analyzer/ras-data/ras-data-parser.hpp>
#include <util/data_file.hpp>
#include <util/trace.hpp>

#include <filesystem>
#include <fstream>
#include <stdexcept>
#include <string>

namespace fs = std::filesystem;

namespace analyzer
{
//------------------------------------------------------------------------------

std::shared_ptr<Resolution>
    RasDataParser::getResolution(const libhei::Signature& i_signature)
{
    nlohmann::json data;

    try
    {
        data = iv_dataFiles.at(i_signature.getChip().getType());
    }
    catch (const std::out_of_range& e)
    {
        trace::err("No RAS data defined for chip type: 0x%08x",
                   i_signature.getChip().getType());
        throw; // caught later downstream
    }

    const auto action = parseSignature(data, i_signature);

    std::shared_ptr<Resolution> resolution;

    try
    {
        resolution = parseAction(data, action);
    }
    catch (...)
    {
        trace::err("Unable to get resolution for action: %s", action.c_str());
        throw; // caught later downstream
    }

    return resolution;
}

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

bool __checkActionForFlag(const std::string& i_action,
                          const std::string& i_flag,
                          const nlohmann::json& i_data)
{
    bool o_isFlagSet = false;

    // Loop through the array of actions.
    for (const auto& a : i_data.at("actions").at(i_action))
    {
        // Get the action type
        auto type = a.at("type").get<std::string>();

        // If the action is another action, recursively call this function
        if ("action" == type)
        {
            auto name = a.at("name").get<std::string>();
            o_isFlagSet = __checkActionForFlag(name, i_flag, i_data);
            if (o_isFlagSet)
            {
                break;
            }
        }
        // If the action is a flag, check if it's the one
        else if ("flag" == type)
        {
            auto name = a.at("name").get<std::string>();
            if (name == i_flag)
            {
                o_isFlagSet = true;
                break;
            }
        }
    }

    return o_isFlagSet;
}

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

bool RasDataParser::isFlagSet(const libhei::Signature& i_signature,
                              const RasDataFlags i_flag) const
{
    bool o_isFlagSet = false;

    // List of all flag enums mapping to their corresponding string
    std::map<RasDataFlags, std::string> flagMap = {
        {SUE_SOURCE, "sue_source"},
        {SUE_SEEN, "sue_seen"},
        {CS_POSSIBLE, "cs_possible"},
        {RECOVERED_ERROR, "recovered_error"},
        {INFORMATIONAL_ONLY, "informational_only"},
        {MNFG_INFORMATIONAL_ONLY, "mnfg_informational_only"},
        {MASK_BUT_DONT_CLEAR, "mask_but_dont_clear"},
        {CRC_RELATED_ERR, "crc_related_err"},
        {CRC_ROOT_CAUSE, "crc_root_cause"},
        {ODP_DATA_CORRUPT_SIDE_EFFECT, "odp_data_corrupt_side_effect"},
        {ODP_DATA_CORRUPT_ROOT_CAUSE, "odp_data_corrupt_root_cause"},
        {ATTN_FROM_OCMB, "attn_from_ocmb"},
    };
    std::string strFlag = flagMap[i_flag];

    // If the input flag does not exist in the map, that's a code bug.
    assert(0 != flagMap.count(i_flag));

    nlohmann::json data;
    try
    {
        data = iv_dataFiles.at(i_signature.getChip().getType());
    }
    catch (const std::out_of_range& e)
    {
        trace::err("No RAS data defined for chip type: 0x%08x",
                   i_signature.getChip().getType());
        throw; // caught later downstream
    }

    // Get the signature keys. All are hex (lower case) with no prefix.
    char buf[5];
    sprintf(buf, "%04x", i_signature.getId());
    std::string id{buf};

    sprintf(buf, "%02x", i_signature.getBit());
    std::string bit{buf};

    // Get the list of flags in string format from the data.
    try
    {
        auto flags = data.at("signatures")
                         .at(id)
                         .at(bit)
                         .at("flags")
                         .get<std::vector<std::string>>();

        // Check if the input flag exists
        if (flags.end() != std::find(flags.begin(), flags.end(), strFlag))
        {
            o_isFlagSet = true;
        }
    }
    catch (const nlohmann::json::out_of_range& e)
    {
        // Do nothing. Assume there is no flag defined. If for some reason
        // the `id` or `bit` were not defined, that will be cause below when the
        // signture is parsed.
    }

    // If the flag hasn't been found, check if it was defined as part of the
    // action for this input signature.
    if (!o_isFlagSet)
    {
        const auto action = parseSignature(data, i_signature);
        try
        {
            __checkActionForFlag(action, strFlag, data);
        }
        catch (const nlohmann::json::out_of_range& e)
        {
            // Again, do nothing. Assume there is no flag defined. If for some
            // reason the action is not defined, that will be handled later when
            // attempting to get the resolution.
        }
    }

    return o_isFlagSet;
}

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

unsigned int
    RasDataParser::getVersion(const libhei::Signature& i_signature) const
{
    unsigned int o_version = 0;

    nlohmann::json data;
    try
    {
        data = iv_dataFiles.at(i_signature.getChip().getType());
    }
    catch (const std::out_of_range& e)
    {
        trace::err("No RAS data defined for chip type: 0x%08x",
                   i_signature.getChip().getType());
        throw; // caught later downstream
    }

    o_version = data.at("version").get<unsigned int>();

    return o_version;
}

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

void RasDataParser::initDataFiles()
{
    iv_dataFiles.clear(); // initially empty

    // Get the RAS data schema files from the package `schema` subdirectory.
    fs::path schemaDir{PACKAGE_DIR "schema"};
    auto schemaRegex = R"(ras-data-schema-v[0-9]{2}\.json)";
    std::vector<fs::path> schemaPaths;
    util::findFiles(schemaDir, schemaRegex, schemaPaths);

    // Parse each of the schema files.
    std::map<unsigned int, nlohmann::json> schemaFiles;
    for (const auto& path : schemaPaths)
    {
        // Trace each data file for debug.
        trace::inf("File found: path=%s", path.string().c_str());

        // Open the file.
        std::ifstream file{path};
        assert(file.good()); // The file must be readable.

        try
        {
            // Parse the JSON.
            auto schema = nlohmann::json::parse(file);

            // Get the schema version.
            auto version = schema.at("version").get<unsigned int>();
            assert(2 <= version); // check support version

            // Keep track of the schemas.
            auto ret = schemaFiles.emplace(version, schema);
            assert(ret.second); // Should not have duplicate entries
        }
        catch (...)
        {
            trace::err("Failed to parse file: %s", path.string().c_str());
            throw; // caught later downstream
        }
    }

    // Get the RAS data files from the package `data` subdirectory.
    fs::path dataDir{PACKAGE_DIR "ras-data"};
    std::vector<fs::path> dataPaths;
    util::findFiles(dataDir, R"(.*\.json)", dataPaths);

    // Parse each of the data files.
    for (const auto& path : dataPaths)
    {
        // Trace each data file for debug.
        trace::inf("File found: path=%s", path.string().c_str());

        // Open the file.
        std::ifstream file{path};
        assert(file.good()); // The file must be readable.

        try
        {
            // Parse the JSON.
            const auto data = nlohmann::json::parse(file);

            // Get the data version.
            auto version = data.at("version").get<unsigned int>();
            assert(2 <= version); // check support version

            // Get the schema for this file.
            auto schema = schemaFiles.at(version);

            // Validate the data against the schema.
            assert(util::validateJson(schema, data));

            // Get the chip model/EC level from the data. The value is currently
            // stored as a string representation of the hex value. So it will
            // have to be converted to an integer.
            libhei::ChipType_t chipType =
                std::stoul(data.at("model_ec").get<std::string>(), 0, 16);

            // So far, so good. Add the entry.
            auto ret = iv_dataFiles.emplace(chipType, data);
            assert(ret.second); // Should not have duplicate entries
        }
        catch (...)
        {
            trace::err("Failed to parse file: %s", path.string().c_str());
            throw; // caught later downstream
        }
    }
}

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

std::string
    RasDataParser::parseSignature(const nlohmann::json& i_data,
                                  const libhei::Signature& i_signature) const
{
    // Get the signature keys. All are hex (lower case) with no prefix.
    char buf[5];
    sprintf(buf, "%04x", i_signature.getId());
    std::string id{buf};

    sprintf(buf, "%02x", i_signature.getBit());
    std::string bit{buf};

    sprintf(buf, "%02x", i_signature.getInstance());
    std::string inst{buf};

    std::string action;

    try
    {
        action =
            i_data.at("signatures").at(id).at(bit).at(inst).get<std::string>();
    }
    catch (const nlohmann::json::out_of_range& e)
    {
        trace::err("No action defined for signature: %s %s %s", id.c_str(),
                   bit.c_str(), inst.c_str());

        // Default to 'level2_M_th1' if no signature is found.
        action = "level2_M_th1";
    }

    // Return the action.
    return action;
}

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

std::tuple<callout::BusType, std::string>
    RasDataParser::parseBus(const nlohmann::json& i_data,
                            const std::string& i_name)
{
    auto bus = i_data.at("buses").at(i_name);

    // clang-format off
    static const std::map<std::string, callout::BusType> m =
    {
        {"SMP_BUS", callout::BusType::SMP_BUS},
        {"OMI_BUS", callout::BusType::OMI_BUS},
    };
    // clang-format on

    auto busType = m.at(bus.at("type").get<std::string>());

    std::string unitPath{}; // default empty if unit does not exist
    if (bus.contains("unit"))
    {
        auto unit = bus.at("unit").get<std::string>();
        unitPath = i_data.at("units").at(unit).get<std::string>();
    }

    return std::make_tuple(busType, unitPath);
}

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

std::shared_ptr<Resolution>
    RasDataParser::parseAction(const nlohmann::json& i_data,
                               const std::string& i_action)
{
    auto o_list = std::make_shared<ResolutionList>();

    // This function will be called recursively and we want to prevent cyclic
    // recursion.
    static std::vector<std::string> stack;
    assert(stack.end() == std::find(stack.begin(), stack.end(), i_action));
    stack.push_back(i_action);

    // Iterate the action list and apply the changes.
    for (const auto& a : i_data.at("actions").at(i_action))
    {
        auto type = a.at("type").get<std::string>();

        if ("action" == type)
        {
            auto name = a.at("name").get<std::string>();

            o_list->push(parseAction(i_data, name));
        }
        else if ("callout_self" == type)
        {
            auto priority = a.at("priority").get<std::string>();
            auto guard = a.at("guard").get<bool>();

            std::string path{}; // Must be empty to callout the chip.

            o_list->push(std::make_shared<HardwareCalloutResolution>(
                path, getPriority(priority), guard));
        }
        else if ("callout_unit" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();
            auto guard = a.at("guard").get<bool>();

            auto path = i_data.at("units").at(name).get<std::string>();

            o_list->push(std::make_shared<HardwareCalloutResolution>(
                path, getPriority(priority), guard));
        }
        else if ("callout_connected" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();
            auto guard = a.at("guard").get<bool>();

            auto busData = parseBus(i_data, name);

            o_list->push(std::make_shared<ConnectedCalloutResolution>(
                std::get<0>(busData), std::get<1>(busData),
                getPriority(priority), guard));
        }
        else if ("callout_bus" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();
            auto guard = a.at("guard").get<bool>();

            auto busData = parseBus(i_data, name);

            o_list->push(std::make_shared<BusCalloutResolution>(
                std::get<0>(busData), std::get<1>(busData),
                getPriority(priority), guard));
        }
        else if ("callout_clock" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();
            auto guard = a.at("guard").get<bool>();

            // clang-format off
            static const std::map<std::string, callout::ClockType> m =
            {
                {"OSC_REF_CLOCK_0", callout::ClockType::OSC_REF_CLOCK_0},
                {"OSC_REF_CLOCK_1", callout::ClockType::OSC_REF_CLOCK_1},
                {"TOD_CLOCK",       callout::ClockType::TOD_CLOCK},
            };
            // clang-format on

            o_list->push(std::make_shared<ClockCalloutResolution>(
                m.at(name), getPriority(priority), guard));
        }
        else if ("callout_procedure" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();

            // clang-format off
            static const std::map<std::string, callout::Procedure> m =
            {
                {"LEVEL2",   callout::Procedure::NEXTLVL},
                {"SUE_SEEN", callout::Procedure::SUE_SEEN},
            };
            // clang-format on

            o_list->push(std::make_shared<ProcedureCalloutResolution>(
                m.at(name), getPriority(priority)));
        }
        else if ("callout_part" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto priority = a.at("priority").get<std::string>();

            // clang-format off
            static const std::map<std::string, callout::PartType> m =
            {
                {"PNOR", callout::PartType::PNOR},
            };
            // clang-format on

            o_list->push(std::make_shared<PartCalloutResolution>(
                m.at(name), getPriority(priority)));
        }
        else if ("plugin" == type)
        {
            auto name = a.at("name").get<std::string>();
            auto inst = a.at("instance").get<unsigned int>();

            o_list->push(std::make_shared<PluginResolution>(name, inst));
        }
        else if ("flag" == type)
        {
            // No action, flags will be handled with the isFlagSet function
        }
        else
        {
            throw std::logic_error("Unsupported action type: " + type);
        }
    }

    // Done with this action pop it off the stack.
    stack.pop_back();

    return o_list;
}

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

callout::Priority RasDataParser::getPriority(const std::string& i_priority)
{
    // clang-format off
    static const std::map<std::string, callout::Priority> m =
    {
        {"HIGH",  callout::Priority::HIGH},
        {"MED",   callout::Priority::MED},
        {"MED_A", callout::Priority::MED_A},
        {"MED_B", callout::Priority::MED_B},
        {"MED_C", callout::Priority::MED_C},
        {"LOW",   callout::Priority::LOW},
    };
    // clang-format on

    return m.at(i_priority);
}

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

} // namespace analyzer
