#include "backup_restore.hpp"

#include "constants.hpp"
#include "event_logger.hpp"
#include "exceptions.hpp"
#include "logger.hpp"
#include "parser.hpp"
#include "types.hpp"

#include <utility/json_utility.hpp>
#include <utility/vpd_specific_utility.hpp>

namespace vpd
{
BackupAndRestoreStatus BackupAndRestore::m_backupAndRestoreStatus =
    BackupAndRestoreStatus::NotStarted;

BackupAndRestore::BackupAndRestore(const nlohmann::json& i_sysCfgJsonObj) :
    m_sysCfgJsonObj(i_sysCfgJsonObj)
{
    std::string l_backupAndRestoreCfgFilePath =
        i_sysCfgJsonObj.value("backupRestoreConfigPath", "");

    m_backupAndRestoreCfgJsonObj =
        jsonUtility::getParsedJson(l_backupAndRestoreCfgFilePath);

    if (m_backupAndRestoreCfgJsonObj.empty())
    {
        throw JsonException("JSON parsing failed",
                            l_backupAndRestoreCfgFilePath);
    }
}

std::tuple<types::VPDMapVariant, types::VPDMapVariant>
    BackupAndRestore::backupAndRestore()
{
    auto l_emptyVariantPair =
        std::make_tuple(std::monostate{}, std::monostate{});

    if (m_backupAndRestoreStatus >= BackupAndRestoreStatus::Invoked)
    {
        logging::logMessage("Backup and restore invoked already.");
        return l_emptyVariantPair;
    }

    m_backupAndRestoreStatus = BackupAndRestoreStatus::Invoked;
    try
    {
        if (m_backupAndRestoreCfgJsonObj.empty() ||
            !m_backupAndRestoreCfgJsonObj.contains("source") ||
            !m_backupAndRestoreCfgJsonObj.contains("destination") ||
            !m_backupAndRestoreCfgJsonObj.contains("type") ||
            !m_backupAndRestoreCfgJsonObj.contains("backupMap"))
        {
            logging::logMessage(
                "Backup restore config JSON is missing necessary tag(s), can't initiate backup and restore.");
            return l_emptyVariantPair;
        }

        std::string l_srcVpdPath;
        types::VPDMapVariant l_srcVpdVariant;
        if (l_srcVpdPath = m_backupAndRestoreCfgJsonObj["source"].value(
                "hardwarePath", "");
            !l_srcVpdPath.empty() && std::filesystem::exists(l_srcVpdPath))
        {
            std::shared_ptr<Parser> l_vpdParser =
                std::make_shared<Parser>(l_srcVpdPath, m_sysCfgJsonObj);
            l_srcVpdVariant = l_vpdParser->parse();
        }
        else if (l_srcVpdPath = m_backupAndRestoreCfgJsonObj["source"].value(
                     "inventoryPath", "");
                 l_srcVpdPath.empty())
        {
            logging::logMessage(
                "Couldn't extract source path, can't initiate backup and restore.");
            return l_emptyVariantPair;
        }

        std::string l_dstVpdPath;
        types::VPDMapVariant l_dstVpdVariant;
        if (l_dstVpdPath = m_backupAndRestoreCfgJsonObj["destination"].value(
                "hardwarePath", "");
            !l_dstVpdPath.empty() && std::filesystem::exists(l_dstVpdPath))
        {
            std::shared_ptr<Parser> l_vpdParser =
                std::make_shared<Parser>(l_dstVpdPath, m_sysCfgJsonObj);
            l_dstVpdVariant = l_vpdParser->parse();
        }
        else if (l_dstVpdPath = m_backupAndRestoreCfgJsonObj["destination"]
                                    .value("inventoryPath", "");
                 l_dstVpdPath.empty())
        {
            logging::logMessage(
                "Couldn't extract destination path, can't initiate backup and restore.");
            return l_emptyVariantPair;
        }

        // Implement backup and restore for IPZ type VPD
        auto l_backupAndRestoreType =
            m_backupAndRestoreCfgJsonObj.value("type", "");
        if (l_backupAndRestoreType.compare("IPZ") == constants::STR_CMP_SUCCESS)
        {
            types::IPZVpdMap l_srcVpdMap;
            if (auto l_srcVpdPtr =
                    std::get_if<types::IPZVpdMap>(&l_srcVpdVariant))
            {
                l_srcVpdMap = *l_srcVpdPtr;
            }
            else if (!std::holds_alternative<std::monostate>(l_srcVpdVariant))
            {
                logging::logMessage("Source VPD is not of IPZ type.");
                return l_emptyVariantPair;
            }

            types::IPZVpdMap l_dstVpdMap;
            if (auto l_dstVpdPtr =
                    std::get_if<types::IPZVpdMap>(&l_dstVpdVariant))
            {
                l_dstVpdMap = *l_dstVpdPtr;
            }
            else if (!std::holds_alternative<std::monostate>(l_dstVpdVariant))
            {
                logging::logMessage("Destination VPD is not of IPZ type.");
                return l_emptyVariantPair;
            }

            backupAndRestoreIpzVpd(l_srcVpdMap, l_dstVpdMap, l_srcVpdPath,
                                   l_dstVpdPath);
            m_backupAndRestoreStatus = BackupAndRestoreStatus::Completed;

            return std::make_tuple(l_srcVpdMap, l_dstVpdMap);
        }
        // Note: add implementation here to support any other VPD type.
    }
    catch (const std::exception& ex)
    {
        logging::logMessage("Back up and restore failed with exception: " +
                            std::string(ex.what()));
    }
    return l_emptyVariantPair;
}

void BackupAndRestore::backupAndRestoreIpzVpd(
    types::IPZVpdMap& io_srcVpdMap, types::IPZVpdMap& io_dstVpdMap,
    const std::string& i_srcPath, const std::string& i_dstPath)
{
    if (!m_backupAndRestoreCfgJsonObj["backupMap"].is_array())
    {
        logging::logMessage(
            "Invalid value found for tag backupMap, in backup and restore config JSON.");
        return;
    }

    const std::string l_srcFruPath =
        jsonUtility::getFruPathFromJson(m_sysCfgJsonObj, i_srcPath);
    const std::string l_dstFruPath =
        jsonUtility::getFruPathFromJson(m_sysCfgJsonObj, i_dstPath);
    if (l_srcFruPath.empty() || l_dstFruPath.empty())
    {
        logging::logMessage(
            "Couldn't find either source or destination FRU path.");
        return;
    }

    const std::string l_srcInvPath =
        jsonUtility::getInventoryObjPathFromJson(m_sysCfgJsonObj, i_srcPath);
    const std::string l_dstInvPath =
        jsonUtility::getInventoryObjPathFromJson(m_sysCfgJsonObj, i_dstPath);
    if (l_srcInvPath.empty() || l_dstInvPath.empty())
    {
        logging::logMessage(
            "Couldn't find either source or destination inventory path.");
        return;
    }

    const std::string l_srcServiceName =
        jsonUtility::getServiceName(m_sysCfgJsonObj, l_srcInvPath);
    const std::string l_dstServiceName =
        jsonUtility::getServiceName(m_sysCfgJsonObj, l_dstInvPath);
    if (l_srcServiceName.empty() || l_dstServiceName.empty())
    {
        logging::logMessage(
            "Couldn't find either source or destination DBus service name.");
        return;
    }

    for (const auto& l_aRecordKwInfo :
         m_backupAndRestoreCfgJsonObj["backupMap"])
    {
        const std::string& l_srcRecordName =
            l_aRecordKwInfo.value("sourceRecord", "");
        const std::string& l_srcKeywordName =
            l_aRecordKwInfo.value("sourceKeyword", "");
        const std::string& l_dstRecordName =
            l_aRecordKwInfo.value("destinationRecord", "");
        const std::string& l_dstKeywordName =
            l_aRecordKwInfo.value("destinationKeyword", "");

        if (l_srcRecordName.empty() || l_dstRecordName.empty() ||
            l_srcKeywordName.empty() || l_dstKeywordName.empty())
        {
            logging::logMessage(
                "Record or keyword not found in the backup and restore config JSON.");
            continue;
        }

        if (!io_srcVpdMap.empty() &&
            io_srcVpdMap.find(l_srcRecordName) == io_srcVpdMap.end())
        {
            logging::logMessage(
                "Record: " + l_srcRecordName +
                ", is not found in the source path: " + i_srcPath);
            continue;
        }

        if (!io_dstVpdMap.empty() &&
            io_dstVpdMap.find(l_dstRecordName) == io_dstVpdMap.end())
        {
            logging::logMessage(
                "Record: " + l_dstRecordName +
                ", is not found in the destination path: " + i_dstPath);
            continue;
        }

        types::BinaryVector l_defaultBinaryValue;
        if (l_aRecordKwInfo.contains("defaultValue") &&
            l_aRecordKwInfo["defaultValue"].is_array())
        {
            l_defaultBinaryValue =
                l_aRecordKwInfo["defaultValue"].get<types::BinaryVector>();
        }
        else
        {
            logging::logMessage(
                "Couldn't read default value for record name: " +
                l_srcRecordName + ", keyword name: " + l_srcKeywordName +
                " from backup and restore config JSON file.");
            continue;
        }

        bool l_isPelRequired = l_aRecordKwInfo.value("isPelRequired", false);

        types::BinaryVector l_srcBinaryValue;
        std::string l_srcStrValue;
        if (!io_srcVpdMap.empty())
        {
            l_srcStrValue = vpdSpecificUtility::getKwVal(
                io_srcVpdMap.at(l_srcRecordName), l_srcKeywordName);

            if (l_srcStrValue.empty())
            {
                std::runtime_error(
                    std::string("Failed to get value for keyword [") +
                    l_srcKeywordName + std::string("]"));
            }

            l_srcBinaryValue =
                types::BinaryVector(l_srcStrValue.begin(), l_srcStrValue.end());
        }
        else
        {
            // Read keyword value from DBus
            const auto l_value = dbusUtility::readDbusProperty(
                l_srcServiceName, l_srcInvPath,
                constants::ipzVpdInf + l_srcRecordName, l_srcKeywordName);
            if (const auto l_binaryValue =
                    std::get_if<types::BinaryVector>(&l_value))
            {
                l_srcBinaryValue = *l_binaryValue;
                l_srcStrValue = std::string(l_srcBinaryValue.begin(),
                                            l_srcBinaryValue.end());
            }
        }

        types::BinaryVector l_dstBinaryValue;
        std::string l_dstStrValue;
        if (!io_dstVpdMap.empty())
        {
            l_dstStrValue = vpdSpecificUtility::getKwVal(
                io_dstVpdMap.at(l_dstRecordName), l_dstKeywordName);

            if (l_dstStrValue.empty())
            {
                std::runtime_error(
                    std::string("Failed to get value for keyword [") +
                    l_dstKeywordName + std::string("]"));
            }

            l_dstBinaryValue =
                types::BinaryVector(l_dstStrValue.begin(), l_dstStrValue.end());
        }
        else
        {
            // Read keyword value from DBus
            const auto l_value = dbusUtility::readDbusProperty(
                l_dstServiceName, l_dstInvPath,
                constants::ipzVpdInf + l_dstRecordName, l_dstKeywordName);
            if (const auto l_binaryValue =
                    std::get_if<types::BinaryVector>(&l_value))
            {
                l_dstBinaryValue = *l_binaryValue;
                l_dstStrValue = std::string(l_dstBinaryValue.begin(),
                                            l_dstBinaryValue.end());
            }
        }

        if (l_srcBinaryValue != l_dstBinaryValue)
        {
            // ToDo: Handle if there is no valid default value in the backup and
            // restore config JSON.
            if (l_dstBinaryValue == l_defaultBinaryValue)
            {
                // Update keyword's value on hardware
                auto l_vpdParser =
                    std::make_shared<Parser>(l_dstFruPath, m_sysCfgJsonObj);

                auto l_bytesUpdatedOnHardware = l_vpdParser->updateVpdKeyword(
                    types::IpzData(l_dstRecordName, l_dstKeywordName,
                                   l_srcBinaryValue));

                /* To keep the data in sync between hardware and parsed map
                 updating the io_dstVpdMap. This should only be done if write
                 on hardware returns success.*/
                if (!io_dstVpdMap.empty() && l_bytesUpdatedOnHardware > 0)
                {
                    io_dstVpdMap[l_dstRecordName][l_dstKeywordName] =
                        l_srcStrValue;
                }
                continue;
            }

            if (l_srcBinaryValue == l_defaultBinaryValue)
            {
                // Update keyword's value on hardware
                auto l_vpdParser =
                    std::make_shared<Parser>(l_srcFruPath, m_sysCfgJsonObj);

                auto l_bytesUpdatedOnHardware = l_vpdParser->updateVpdKeyword(
                    types::IpzData(l_srcRecordName, l_srcKeywordName,
                                   l_dstBinaryValue));

                /* To keep the data in sync between hardware and parsed map
                 updating the io_srcVpdMap. This should only be done if write
                 on hardware returns success.*/
                if (!io_srcVpdMap.empty() && l_bytesUpdatedOnHardware > 0)
                {
                    io_srcVpdMap[l_srcRecordName][l_srcKeywordName] =
                        l_dstStrValue;
                }
            }
            else
            {
                /**
                 * Update io_srcVpdMap to publish the same data on DBus, which
                 * is already present on the DBus. Because after calling
                 * backupAndRestore API the map value will get published to DBus
                 * in the worker flow.
                 */
                if (!io_srcVpdMap.empty() && io_dstVpdMap.empty())
                {
                    io_srcVpdMap[l_srcRecordName][l_srcKeywordName] =
                        l_dstStrValue;
                }

                std::string l_errorMsg(
                    "Mismatch found between source and destination VPD for record : " +
                    l_srcRecordName + " and keyword : " + l_srcKeywordName +
                    " . Value read from source : " +
                    commonUtility::convertByteVectorToHex(l_srcBinaryValue) +
                    " . Value read from destination : " +
                    commonUtility::convertByteVectorToHex(l_dstBinaryValue));

                EventLogger::createSyncPel(
                    types::ErrorType::VpdMismatch, types::SeverityType::Warning,
                    __FILE__, __FUNCTION__, 0, l_errorMsg, std::nullopt,
                    std::nullopt, std::nullopt, std::nullopt);
            }
        }
        else if (l_srcBinaryValue == l_defaultBinaryValue &&
                 l_dstBinaryValue == l_defaultBinaryValue && l_isPelRequired)
        {
            std::string l_errorMsg(
                "Default value found on both source and destination VPD, for record: " +
                l_srcRecordName + " and keyword: " + l_srcKeywordName);

            EventLogger::createSyncPel(
                types::ErrorType::DefaultValue, types::SeverityType::Error,
                __FILE__, __FUNCTION__, 0, l_errorMsg, std::nullopt,
                std::nullopt, std::nullopt, std::nullopt);
        }
    }
}

void BackupAndRestore::setBackupAndRestoreStatus(
    const BackupAndRestoreStatus& i_status)
{
    m_backupAndRestoreStatus = i_status;
}

int BackupAndRestore::updateKeywordOnPrimaryOrBackupPath(
    const std::string& i_fruPath,
    [[maybe_unused]] const types::WriteVpdParams& i_paramsToWriteData)
    const noexcept
{
    if (i_fruPath.empty())
    {
        logging::logMessage("Given FRU path is empty.");
        return constants::FAILURE;
    }

    if (m_backupAndRestoreCfgJsonObj.contains("source") &&
        m_backupAndRestoreCfgJsonObj["source"].value("hardwarePath", "") ==
            i_fruPath &&
        m_backupAndRestoreCfgJsonObj.contains("destination") &&
        !m_backupAndRestoreCfgJsonObj["destination"]
             .value("hardwarePath", "")
             .empty())
    {
        // ToDo implementation needs to be added
    }
    else if (m_backupAndRestoreCfgJsonObj.contains("destination") &&
             m_backupAndRestoreCfgJsonObj["destination"].value(
                 "hardwarePath", "") == i_fruPath &&
             m_backupAndRestoreCfgJsonObj.contains("source") &&
             !m_backupAndRestoreCfgJsonObj["source"]
                  .value("hardwarePath", "")
                  .empty())
    {
        // ToDo implementation needs to be added
    }

    return constants::SUCCESS;
}

} // namespace vpd
