#include "include/power_rail/power_rail_utility.hpp"

#include "include/common_utility.hpp"

#include <utility>

namespace powerfault
{

uint8_t readCPLDFlag(const uint8_t bus, const uint8_t addr, const uint8_t reg)
{
    std::vector<uint8_t> writeData = {0x00, reg};
    std::vector<uint8_t> readData = util::i2cWriteRead(bus, addr, writeData,
                                                       writeData.size(), 1);

    if (readData.empty())
    {
        lg2::error("Failed to read CPLD flag");
        return 0;
    }

    return readData[0];
}

void executeAction(uint8_t bus, uint8_t addr, uint8_t action)
{
    uint8_t commandCode = 0x00;
    uint8_t actionReg = 0x30;
    uint8_t statusReg = 0x2D;
    uint8_t clearFlag = 0x00;
    uint8_t cpldFlag = 0x00;
    // clear action flag
    std::vector<uint8_t> writeData = {commandCode, actionReg, clearFlag};
    util::i2cWriteRead(bus, addr, writeData, writeData.size(), 0);

    switch (action)
    {
        case 0x02: // read 0x30 bit1
        case 0x04: // erase 0x30 bit2
            writeData = {commandCode, actionReg, action};
            util::i2cWriteRead(bus, addr, writeData, writeData.size(), 0);
            do
            {
                cpldFlag = readCPLDFlag(bus, addr, statusReg);
                if ((cpldFlag & kCpldUfmComponentFaultFlag) != 0)
                {
                    lg2::error("UFM component fault");
                    break;
                }
            } while ((cpldFlag & kCpldBusyFlag) != 0);
            break;
        case 0x08: // disable 0x30 bit3
            writeData = {commandCode, actionReg, action};
            util::i2cWriteRead(bus, addr, writeData, writeData.size(), 0);
            break;
        default:
            break;
    }
}

std::optional<RailInfo> processRail(const nlohmann::json& rail)
{
    auto requiredFields = {kName, kType, kSource, kBus, kAddress, kBit};

    for (const auto& field : requiredFields)
    {
        if (!rail.contains(field) &&
            !(rail[kType] == kSequencer && field == kBit))
        {
            lg2::error("Rail object: {RAIL}", "RAIL", rail.dump());
            lg2::error("Rail object is missing the {FIELD}", "FIELD", field);
            return std::nullopt;
        }
    }

    try
    {
        RailInfo railInfo(
            rail[kName].get<std::string>(), rail[kType].get<std::string>(),
            rail[kSource].get<std::string>(), util::parseDec(rail[kBus]),
            util::parseHexByte(rail[kAddress]));

        if (railInfo.type == kCPLD)
        {
            if (rail.contains(kBit))
            {
                railInfo.bit = util::parseDec(rail[kBit]);
            }
            if (rail.contains(kReg))
            {
                railInfo.reg = util::parseHexByte(rail[kReg]);
            }
            if (rail.contains(kReverseFlag))
            {
                railInfo.reverse_flag = util::parseDec(rail[kReverseFlag]);
            }
        }
        else if (railInfo.type == kSequencer && rail.contains(kPage))
        {
            railInfo.page = util::parseDec(rail[kPage]);
        }
        else
        {
            lg2::error("Unknown rail type: {TYPE}", "TYPE", railInfo.type);
            return std::nullopt;
        }

        return railInfo;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception occurred while processing rail: {ERROR}", "ERROR",
                   e.what());
        return std::nullopt;
    }
}

std::pair<std::vector<std::string>, std::vector<std::string>>
    readPriorityFiles(const fs::path& priorityDirPath)
{
    fs::path zigguratPriorityPath = priorityDirPath / "ziggurat.json";
    fs::path peripheralPriorityPath = priorityDirPath / "peripheral.json";

    std::vector<std::string> zigguratPriority;
    std::vector<std::string> peripheralPriority;

    if (fs::exists(zigguratPriorityPath))
    {
        std::ifstream ifs(zigguratPriorityPath);
        json zigguratPriorityJson;
        ifs >> zigguratPriorityJson;
        zigguratPriority = zigguratPriorityJson.get<std::vector<std::string>>();
    }

    if (fs::exists(peripheralPriorityPath))
    {
        std::ifstream ifs(peripheralPriorityPath);
        json peripheralPriorityJson;
        ifs >> peripheralPriorityJson;
        peripheralPriority =
            peripheralPriorityJson.get<std::vector<std::string>>();
    }

    lg2::info("Ziggurat Priority JSON content: {CONTENT}", "CONTENT",
              json(zigguratPriority).dump());
    lg2::info("Peripheral Priority JSON content: {CONTENT}", "CONTENT",
              json(peripheralPriority).dump());

    return {zigguratPriority, peripheralPriority};
}

std::pair<json, json> readRegisterMapFiles(const fs::path& registerMapDirPath)
{
    fs::path cpldRegisterMapPath = registerMapDirPath / "CPLD.json";
    fs::path sequencerRegisterMapPath = registerMapDirPath / "Sequencer.json";

    json cpldRegisterMap;
    json sequencerRegisterMap;

    if (fs::exists(cpldRegisterMapPath))
    {
        std::ifstream ifs(cpldRegisterMapPath);
        ifs >> cpldRegisterMap;
    }

    if (fs::exists(sequencerRegisterMapPath))
    {
        std::ifstream ifs(sequencerRegisterMapPath);
        ifs >> sequencerRegisterMap;
    }

    return {cpldRegisterMap, sequencerRegisterMap};
}

std::map<std::string, json> collectPowerRails(const json& registerMap,
                                              std::string_view registerType)
{
    std::map<std::string, json> railToConfigMap;

    for (const auto& config : registerMap)
    {
        if (registerType == kCPLD && config.contains(kCPLDRegisters))
        {
            for (const auto& cpldRegister : config[kCPLDRegisters])
            {
                if (cpldRegister.contains(kBitToPowerRailMap))
                {
                    std::vector<std::string> reverseFlags = {};
                    if (cpldRegister.contains(kReverseFlag))
                    {
                        reverseFlags = cpldRegister[kReverseFlag];
                    }

                    for (const auto& [bit, powerRail] :
                         cpldRegister[kBitToPowerRailMap].items())
                    {
                        const std::string reverseFlag =
                            std::find(reverseFlags.begin(), reverseFlags.end(),
                                      bit) != reverseFlags.end()
                                ? "1"
                                : "0";
                        railToConfigMap[powerRail] = {
                            {kName, powerRail},
                            {kType, kCPLD},
                            {kSource, config[kSource]},
                            {kBus, config[kBus]},
                            {kAddress, config[kAddress]},
                            {kReg, cpldRegister[kRegister]},
                            {kBit, bit},
                            {kReverseFlag, reverseFlag}};
                    }
                }
            }
        }
        else if (registerType == kSequencer &&
                 config.contains(kSequencerRegisters))
        {
            for (const auto& sequencerRegister : config[kSequencerRegisters])
            {
                if (sequencerRegister.contains(kPageToPowerRailMap))
                {
                    for (const auto& [page, powerRail] :
                         sequencerRegister[kPageToPowerRailMap].items())
                    {
                        railToConfigMap[powerRail] = {
                            {kName, powerRail},
                            {kType, kSequencer},
                            {kSource, config[kSource]},
                            {kBus, config[kBus]},
                            {kAddress, config[kAddress]},
                            {kReg, sequencerRegister[kRegister]},
                            {kPage, page}};
                    }
                }
            }
        }
    }

    return railToConfigMap;
}

ProcessResult
    processPriorityList(const std::vector<std::string>& priorityList,
                        const std::map<std::string, RailInfo>& railInfoMap,
                        const fs::path& logDirPath,
                        const std::map<uint8_t, uint8_t>& cpldRegValues)
{
    ProcessResult result;
    result.success = true;
    result.hasErrorInZiggurat = false;
    result.runtime = false;

    for (const auto& railName : priorityList)
    {
        auto it = railInfoMap.find(railName);
        if (it != railInfoMap.end())
        {
            const RailInfo& railInfo = it->second;

            fs::path filePath = logDirPath / (railInfo.name + ".log");
            std::ofstream ofs(filePath);

            if (railInfo.type == kCPLD)
            {
                ProcessResult cpldResult = handleCPLDRail(railInfo,
                                                          cpldRegValues, ofs);
                if (!cpldResult.success)
                {
                    result.success = false;
                    return result;
                }
                result.runtime = cpldResult.runtime;
                result.hasErrorInZiggurat = cpldResult.hasErrorInZiggurat ||
                                            result.hasErrorInZiggurat;
                result.powerFaultRails.insert(
                    result.powerFaultRails.end(),
                    cpldResult.powerFaultRails.begin(),
                    cpldResult.powerFaultRails.end());
            }
            else if (railInfo.type == kSequencer)
            {
                ProcessResult sequencerResult = handleSequencerRail(railInfo,
                                                                    ofs);
                if (!sequencerResult.success)
                {
                    result.success = false;
                    return result;
                }
                result.hasErrorInZiggurat =
                    sequencerResult.hasErrorInZiggurat ||
                    result.hasErrorInZiggurat;
                result.powerFaultRails.insert(
                    result.powerFaultRails.end(),
                    sequencerResult.powerFaultRails.begin(),
                    sequencerResult.powerFaultRails.end());
            }

            ofs.close();

            if (result.hasErrorInZiggurat)
            {
                showPowerFault(result.runtime, result.powerFaultRails,
                               logDirPath);
                return result;
            }
        }
    }

    return result;
}

ProcessResult handleCPLDRail(const RailInfo& railInfo,
                             std::map<uint8_t, uint8_t> cpldRegValues,
                             std::ofstream& logFile)
{
    ProcessResult result;
    result.success = true;
    result.hasErrorInZiggurat = false;
    result.runtime = false;
    result.cpldRegValues = std::move(cpldRegValues);

    auto it = result.cpldRegValues.find(railInfo.reg);
    if (it == result.cpldRegValues.end())
    {
        lg2::error("Rail {RAIL} not found in CPLD register values", "RAIL",
                   railInfo.name);
        result.success = false;
        return result;
    }

    uint8_t regValue = it->second;
    std::string regValueHex = util::byteArrayToHexString(&regValue, 1);
    boost::algorithm::trim(regValueHex);
    logFile << util::getCurrentTimestamp() << " " << railInfo.name + ": "
            << regValueHex << '\n';

    if (railInfo.name == kCPLDRuntimeFlag)
    {
        result.runtime = (regValue & 0x1) == 1;
    }
    else if (((regValue & (1 << railInfo.bit)) ^ railInfo.reverse_flag) != 0)
    {
        result.powerFaultRails.emplace_back(railInfo.name);
        if (railInfo.source == kZiggurat)
        {
            result.hasErrorInZiggurat = true;
        }
    }

    return result;
}

ProcessResult handleSequencerRail(const RailInfo& railInfo,
                                  std::ofstream& logFile)
{
    ProcessResult result;
    result.success = true;
    result.hasErrorInZiggurat = false;

    std::string railResult = fromMax34451Mb(railInfo.page);
    logFile << railInfo.name + ": " << railResult << '\n';

    if (railResult == "Fault")
    {
        result.powerFaultRails.emplace_back(railInfo.name);
        if (railInfo.source == kZiggurat)
        {
            result.hasErrorInZiggurat = true;
        }
    }

    return result;
}

std::pair<uint8_t, uint8_t>
    getCPLDRegisterRange(const std::map<std::string, RailInfo>& railInfoMap,
                         std::string_view cpldType)
{
    uint8_t min = 0xFF;
    uint8_t max = 0x00;
    for (const auto& [railName, railObject] : railInfoMap)
    {
        if (railObject.source == cpldType)
        {
            min = std::min(min, railObject.reg);
            max = std::max(max, railObject.reg);
        }
    }
    if (min > max)
    {
        lg2::error("Failed to get min and max register values");
        return std::make_pair(0, 0);
    }

    return std::make_pair(min, max);
}

std::pair<uint8_t, uint8_t>
    getCPLDBusAndAddress(const std::map<std::string, RailInfo>& railInfoMap,
                         std::string_view source)
{
    for (const auto& [railName, railObject] : railInfoMap)
    {
        if (railObject.source == source)
        {
            return std::make_pair(railObject.bus, railObject.address);
        }
    }
    return std::make_pair(0, 0);
}

std::map<uint8_t, uint8_t> readCPLDRegisters(const uint8_t bus,
                                             const uint8_t address,
                                             const uint8_t minReg,
                                             const size_t regRange,
                                             const bool& setCPLDFlag)
{
    std::map<uint8_t, uint8_t> registerValues;
    std::vector<uint8_t> writeData = {0x00, minReg};
    std::vector<uint8_t> readData(regRange, 0);

    if (setCPLDFlag)
    {
        executeAction(bus, address, kCpldDisableFlag);
        executeAction(bus, address, kCpldReadFlag);
        usleep(16);
    }

    try
    {
        readData = util::i2cWriteRead(bus, address, writeData, writeData.size(),
                                      regRange);

        if (readData.empty() || readData.size() != regRange)
        {
            for (size_t i = 0; i < regRange; i++)
            {
                registerValues[minReg + i] = 0;
            }
            return registerValues;
        }

        for (size_t i = 0; i < regRange; i++)
        {
            registerValues[minReg + i] = readData[i];
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("{ERROR}", "ERROR", e.what());
        for (size_t i = 0; i < regRange; i++)
        {
            registerValues[minReg + i] = 0;
        }
    }

    if (setCPLDFlag)
    {
        // Make CPLD execute erase action
        executeAction(bus, address, kCpldEraseFlag);
        // delay 1.6 seconds to make sure CPLD erase UFM successfully
        usleep(1600000);
        // clear action flag
        executeAction(bus, address, kCpldClearFlag);
    }
    return registerValues;
}

std::pair<bool, std::map<std::string, RailInfo>>
    getRailInfoMap(const fs::path& registerMapDirPath)
{
    bool setCPLDFlag = false;
    auto [cpldRegisterMap,
          sequencerRegisterMap] = readRegisterMapFiles(registerMapDirPath);

    for (const auto& config : cpldRegisterMap)
    {
        if (config.contains(kSetCPLDFlag))
        {
            setCPLDFlag = config[kSetCPLDFlag].get<bool>();
            break;
        }
    }

    std::map<std::string, json> railToConfigMapCPLD =
        collectPowerRails(cpldRegisterMap, kCPLD);
    std::map<std::string, json> railToConfigMapSequencer =
        collectPowerRails(sequencerRegisterMap, kSequencer);

    std::map<std::string, json> railToConfigMap;
    railToConfigMap.insert(railToConfigMapCPLD.begin(),
                           railToConfigMapCPLD.end());
    railToConfigMap.insert(railToConfigMapSequencer.begin(),
                           railToConfigMapSequencer.end());

    std::map<std::string, RailInfo> railInfoMap;
    for (const auto& [railName, railObject] : railToConfigMap)
    {
        auto railInfo = processRail(railObject);
        if (railInfo.has_value())
        {
            railInfoMap.emplace(railName, railInfo.value());
        }
        else
        {
            lg2::error("Failed to process rail: {RAIL}", "RAIL", railName);
        }
    }

    return {setCPLDFlag, railInfoMap};
}

std::map<uint8_t, uint8_t>
    getCPLDRegValues(const std::map<std::string, RailInfo>& railInfoMap,
                     const bool& setCPLDFlag)
{
    auto [bus, addr] = getCPLDBusAndAddress(railInfoMap, kCPLDM);
    auto [minReg, maxReg] = getCPLDRegisterRange(railInfoMap, kCPLDM);
    size_t regRange = maxReg - minReg + 1;

    lg2::info("Min register value: {MIN}", "MIN", minReg);
    lg2::info("Max register value: {MAX}", "MAX", maxReg);
    lg2::info("Register range: {RANGE}", "RANGE", regRange);
    lg2::info("CPLD bus: {BUS}", "BUS", static_cast<int>(bus));
    lg2::info("CPLD address: {ADDR}", "ADDR", static_cast<int>(addr));

    std::map<uint8_t, uint8_t> cpldRegValues =
        readCPLDRegisters(bus, addr, minReg, regRange, setCPLDFlag);

    return cpldRegValues;
}

bool logRailState(const fs::path& priorityDirPath,
                  const fs::path& registerMapDirPath,
                  const fs::path& logDirPath,
                  std::string_view specifiedRailName)
{
    auto [setCPLDFlag, railInfoMap] = getRailInfoMap(registerMapDirPath);

    std::map<uint8_t, uint8_t> cpldRegValues = getCPLDRegValues(railInfoMap,
                                                                setCPLDFlag);

    if (!specifiedRailName.empty())
    {
        if (railInfoMap.find(std::string(specifiedRailName)) ==
            railInfoMap.end())
        {
            lg2::error("Specified rail {RAIL} does not exist", "RAIL",
                       std::string(specifiedRailName));
            return false;
        }

        std::vector<std::string> priorityList;
        priorityList.emplace_back(specifiedRailName);
        ProcessResult result = processPriorityList(priorityList, railInfoMap,
                                                   logDirPath, cpldRegValues);

        if (!result.success)
        {
            lg2::error("Failed to process specified rail");
            return false;
        }
        if (result.hasErrorInZiggurat)
        {
            showPowerFault(result.runtime, result.powerFaultRails, logDirPath);
            return true;
        }

        return true;
    }

    auto [zigguratPriority,
          peripheralPriority] = readPriorityFiles(priorityDirPath);

    ProcessResult result = processPriorityList(zigguratPriority, railInfoMap,
                                               logDirPath, cpldRegValues);

    if (!result.success)
    {
        lg2::error("Failed to process ziggurat priority list");
        return false;
    }

    if (!result.hasErrorInZiggurat)
    {
        result = processPriorityList(peripheralPriority, railInfoMap,
                                     logDirPath, cpldRegValues);
        if (!result.success)
        {
            lg2::error("Failed to process peripheral priority list");
            return false;
        }
    }

    showPowerFault(result.runtime, result.powerFaultRails, logDirPath);
    return true;
}

std::string fromMax34451Mb(const uint8_t page)
{
    const uint8_t kMax34451Mbbus = 44;
    const uint8_t kMax34451MbAddress = 0x59;

    try
    {
        util::i2cWriteByte(kMax34451Mbbus, kMax34451MbAddress, 0x00, page);
    }
    catch (const std::runtime_error& e)
    {
        return "set page failed";
    }

    uint8_t regVal = 0;
    try
    {
        regVal = util::i2cReadByte(kMax34451Mbbus, kMax34451MbAddress, 0x7a);
    }
    catch (const std::runtime_error& e)
    {
        return "read register failed";
    }

    if (max34451::checkPowerRailFault(regVal, false))
    {
        return "Fault";
    }
    return "Normal";
}

void showPowerFault(const bool runtime, const PowerFaultRail& powerFaultRails,
                    const fs::path& logDirPath)
{
    std::string message;
    std::string rails;
    for (const auto& powerFaultRail : powerFaultRails)
    {
        rails += powerFaultRail + "\n";
    }

    if (!powerFaultRails.empty())
    {
        if (runtime)
        {
            message = "The following rail occur power fault during runtime";
        }
        else
        {
            message = "The following rail occur power fault during power up";
        }
        message += "\n" + rails;
        lg2::error("{MSG}", "MSG", message);
        util::summarizeLog(getDbusUtil(), message, logDirPath,
                           util::kSumLogName);
    }
}

} // namespace powerfault
