#include "tool_constants.hpp"
#include "tool_utils.hpp"
#include "vpd_tool.hpp"

#include <CLI/CLI.hpp>

#include <filesystem>
#include <iostream>

/**
 * @brief Resets the VPD on DBus for all the Frus.
 *
 * API clears the inventory persisted data and restarts the phosphor inventory
 * manager(PIM) DBus service and the VPD manager service. VPD manager service
 * collects the VPD for all the FRU's listed on the system config JSON and calls
 * PIM to publish VPD on DBus.
 *
 * Note: Force reset only happens if chassis is powered off.
 *
 * @return On success returns 0, otherwise returns -1.
 */
int forceReset()
{
    if (vpd::utils::isChassisPowerOff())
    {
        vpd::VpdTool l_vpdToolObj;
        return l_vpdToolObj.resetVpdOnDbus();
    }

    std::cerr
        << "The chassis power state is not Off. Force reset operation is not allowed."
        << std::endl;
    return vpd::constants::FAILURE;
}

/**
 * @brief API to perform manufacturing clean.
 *
 * @param[in] i_mfgCleanConfirmFlag - Confirmation flag to perform manufacturing
 * clean.
 * @param[in] i_syncBiosAttributesFlag - Flag which specifies whether
 * BIOS attribute related keywords need to be synced from BIOS Config Manager
 * instead of being reset to default value.
 *
 * @return Status returned by cleanSystemVpd operation, success otherwise.
 */
int doMfgClean(const auto& i_mfgCleanConfirmFlag,
               const auto& i_syncBiosAttributesFlag)
{
    if (i_mfgCleanConfirmFlag->empty())
    {
        constexpr auto MAX_CONFIRMATION_STR_LENGTH{3};
        std::string l_confirmation{};
        std::cout
            << "This option resets some of the system VPD keywords to their default values. Do you really wish to proceed further?[yes/no]:";
        std::cin >> std::setw(MAX_CONFIRMATION_STR_LENGTH) >> l_confirmation;

        if (l_confirmation != "yes")
        {
            return vpd::constants::SUCCESS;
        }
    }

    vpd::VpdTool l_vpdToolObj;
    return l_vpdToolObj.cleanSystemVpd(!i_syncBiosAttributesFlag->empty());
}

/**
 * @brief API to write keyword's value.
 *
 * @param[in] i_hardwareFlag - Flag to perform write on hardware.
 * @param[in] i_keywordValueOption - Option to read keyword value from command.
 * @param[in] i_vpdPath - DBus object path or EEPROM path.
 * @param[in] i_recordName - Record to be updated.
 * @param[in] i_keywordName - Keyword to be updated.
 * @param[in] i_keywordValue - Value to be updated in keyword.
 *
 * @return Status of writeKeyword operation, failure otherwise.
 */
int writeKeyword(const auto& i_hardwareFlag, const auto& i_keywordValueOption,
                 const std::string& i_vpdPath, const std::string& i_recordName,
                 const std::string& i_keywordName,
                 const std::string& i_keywordValue)
{
    std::error_code l_ec;

    if (!i_hardwareFlag->empty() && !std::filesystem::exists(i_vpdPath, l_ec))
    {
        std::cerr << "Given EEPROM file path doesn't exist[" + i_vpdPath << "]."
                  << std::endl;
        if (l_ec)
        {
            std::cerr << "Reason: " + l_ec.message() << std::endl;
        }
        return vpd::constants::FAILURE;
    }

    if (!i_keywordValueOption->empty() && i_keywordValue.empty())
    {
        std::cerr
            << "Please provide keyword value.\nUse --value/--file to give "
               "keyword value. Refer --help."
            << std::endl;
        return vpd::constants::FAILURE;
    }

    if (i_keywordValueOption->empty())
    {
        std::cerr
            << "Please provide keyword value.\nUse --value/--file to give "
               "keyword value. Refer --help."
            << std::endl;
        return vpd::constants::FAILURE;
    }

    vpd::VpdTool l_vpdToolObj;
    return l_vpdToolObj.writeKeyword(i_vpdPath, i_recordName, i_keywordName,
                                     i_keywordValue, !i_hardwareFlag->empty());
}

/**
 * @brief API to read keyword's value.
 *
 * @param[in] i_hardwareFlag - Flag to perform write on hardware.
 * @param[in] i_vpdPath - DBus object path or EEPROM path.
 * @param[in] i_recordName - Record to be updated.
 * @param[in] i_keywordName - Keyword to be updated.
 * @param[in] i_filePath - File path to save keyword's read value.
 *
 * @return On success return 0, otherwise return -1.
 */
int readKeyword(const auto& i_hardwareFlag, const std::string& i_vpdPath,
                const std::string& i_recordName,
                const std::string& i_keywordName, const std::string& i_filePath)
{
    std::error_code l_ec;

    if (!i_hardwareFlag->empty() && !std::filesystem::exists(i_vpdPath, l_ec))
    {
        std::string l_errMessage{
            "Given EEPROM file path doesn't exist : " + i_vpdPath};

        if (l_ec)
        {
            l_errMessage += ". filesystem call exists failed, reason: " +
                            l_ec.message();
        }

        std::cerr << l_errMessage << std::endl;
        return vpd::constants::FAILURE;
    }

    bool l_isHardwareOperation = (!i_hardwareFlag->empty() ? true : false);

    vpd::VpdTool l_vpdToolObj;
    return l_vpdToolObj.readKeyword(i_vpdPath, i_recordName, i_keywordName,
                                    l_isHardwareOperation, i_filePath);
}

/**
 * @brief API to check option value pair in the tool command.
 *
 * In VPD tool command, some of the option(s) mandate values to be passed along
 * with the option. This API based on option, detects those mandatory value(s).
 *
 * @param[in] i_objectOption - Option to pass object path.
 * @param[in] i_vpdPath - Object path, DBus or EEPROM.
 * @param[in] i_recordOption - Option to pass record name.
 * @param[in] i_recordName - Record name.
 * @param[in] i_keywordOption - Option to pass keyword name.
 * @param[in] i_keywordName - Keyword name.
 * @param[in] i_fileOption - Option to pass file path.
 * @param[in] i_filePath - File path.
 *
 * @return Success if corresponding value is found against option, failure
 * otherwise.
 */
int checkOptionValuePair(const auto& i_objectOption, const auto& i_vpdPath,
                         const auto& i_recordOption, const auto& i_recordName,
                         const auto& i_keywordOption, const auto& i_keywordName,
                         const auto& i_fileOption, const auto& i_filePath)
{
    if (!i_objectOption->empty() && i_vpdPath.empty())
    {
        std::cout << "Given path is empty." << std::endl;
        return vpd::constants::FAILURE;
    }

    if (!i_recordOption->empty() &&
        (i_recordName.size() != vpd::constants::RECORD_SIZE))
    {
        std::cerr << "Record " << i_recordName << " is not supported."
                  << std::endl;
        return vpd::constants::FAILURE;
    }

    if (!i_keywordOption->empty() &&
        (i_keywordName.size() != vpd::constants::KEYWORD_SIZE))
    {
        std::cerr << "Keyword " << i_keywordName << " is not supported."
                  << std::endl;
        return vpd::constants::FAILURE;
    }

    if (!i_fileOption->empty() && i_filePath.empty())
    {
        std::cout << "File path is empty." << std::endl;
        return vpd::constants::FAILURE;
    }

    return vpd::constants::SUCCESS;
}

/**
 * @brief API to create app footer.
 *
 * @param[in] i_app - CLI::App object.
 */
void updateFooter(CLI::App& i_app)
{
    i_app.footer(
        "Read:\n"
        "    IPZ Format:\n"
        "        From DBus to console: "
        "vpd-tool -r -O <DBus Object Path> -R <Record Name> -K <Keyword Name>\n"
        "        From DBus to file: "
        "vpd-tool -r -O <DBus Object Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
        "        From hardware to console: "
        "vpd-tool -r -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name>\n"
        "        From hardware to file: "
        "vpd-tool -r -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
        "Write:\n"
        "    IPZ Format:\n"
        "        On DBus: "
        "vpd-tool -w/-u -O <DBus Object Path> -R <Record Name> -K <Keyword Name> -V <Keyword Value>\n"
        "        On DBus, take keyword value from file:\n"
        "              vpd-tool -w/-u -O <DBus Object Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
        "        On hardware: "
        "vpd-tool -w/-u -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> -V <Keyword Value>\n"
        "        On hardware, take keyword value from file:\n"
        "              vpd-tool -w/-u -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
        "Dump Object:\n"
        "    From DBus to console: "
        "vpd-tool -o -O <DBus Object Path>\n"
        "Fix System VPD:\n"
        "    vpd-tool --fixSystemVPD\n"
        "MfgClean:\n"
        "        Flag to clean and reset specific keywords on system VPD to its default value.\n"
        "        vpd-tool --mfgClean\n"
        "        To sync BIOS attribute related keywords with BIOS Config Manager:\n"
        "        vpd-tool --mfgClean --syncBiosAttributes\n"
        "Dump Inventory:\n"
        "   From DBus to console in JSON format: "
        "vpd-tool -i\n"
        "   From DBus to console in Table format: "
        "vpd-tool -i -t\n"
        "Force Reset:\n"
        "   vpd-tool --forceReset\n");
}

int main(int argc, char** argv)
{
    CLI::App l_app{"VPD Command Line Tool"};

    std::string l_vpdPath{};
    std::string l_recordName{};
    std::string l_keywordName{};
    std::string l_filePath{};
    std::string l_keywordValue{};

    updateFooter(l_app);

    auto l_objectOption =
        l_app.add_option("--object, -O", l_vpdPath, "File path");
    auto l_recordOption =
        l_app.add_option("--record, -R", l_recordName, "Record name");
    auto l_keywordOption =
        l_app.add_option("--keyword, -K", l_keywordName, "Keyword name");

    auto l_fileOption = l_app.add_option(
        "--file", l_filePath,
        "Absolute file path,\nNote: For write operation, file should contain keyword’s value in either ascii or in hex format.");

    auto l_keywordValueOption =
        l_app.add_option("--value, -V", l_keywordValue,
                         "Keyword value in ascii/hex format."
                         " ascii ex: 01234; hex ex: 0x30313233");

    auto l_hardwareFlag =
        l_app.add_flag("--Hardware, -H", "CAUTION: Developer only option.");

    auto l_readFlag = l_app.add_flag("--readKeyword, -r", "Read keyword")
                          ->needs(l_objectOption)
                          ->needs(l_recordOption)
                          ->needs(l_keywordOption);

    auto l_writeFlag =
        l_app
            .add_flag(
                "--writeKeyword, -w,--updateKeyword, -u",
                "Write keyword,\nNote: In case DBus path is provided, both EEPROM and DBus are updated with the given keyword's value.\nIn case EEPROM path is provided, only the given EEPROM is updated with the given keyword's value.")
            ->needs(l_objectOption)
            ->needs(l_recordOption)
            ->needs(l_keywordOption);

    // ToDo: Take offset value from user for hardware path.

    auto l_dumpObjFlag =
        l_app
            .add_flag("--dumpObject, -o",
                      "Dump specific properties of an inventory object")
            ->needs(l_objectOption);

    auto l_fixSystemVpdFlag = l_app.add_flag(
        "--fixSystemVPD",
        "Use this option to interactively fix critical system VPD keywords");
    auto l_dumpInventoryFlag =
        l_app.add_flag("--dumpInventory, -i", "Dump all the inventory objects");

    auto l_mfgCleanFlag = l_app.add_flag(
        "--mfgClean", "Manufacturing clean on system VPD keyword");

    auto l_mfgCleanConfirmFlag = l_app.add_flag(
        "--yes", "Using this flag with --mfgClean option, assumes "
                 "yes to proceed without confirmation.");

    auto l_dumpInventoryTableFlag =
        l_app.add_flag("--table, -t", "Dump inventory in table format");

    auto l_mfgCleanSyncBiosAttributesFlag = l_app.add_flag(
        "--syncBiosAttributes, -s",
        "Using this flag with --mfgClean option, Syncs the BIOS attribute related keywords from BIOS Config Manager service instead resetting keyword's value to default value");

    auto l_forceResetFlag = l_app.add_flag(
        "--forceReset, -f, -F",
        "Force collect for hardware. CAUTION: Developer only option.");

    CLI11_PARSE(l_app, argc, argv);

    if (checkOptionValuePair(l_objectOption, l_vpdPath, l_recordOption,
                             l_recordName, l_keywordOption, l_keywordName,
                             l_fileOption, l_filePath) ==
        vpd::constants::FAILURE)
    {
        return vpd::constants::FAILURE;
    }

    if (!l_readFlag->empty())
    {
        return readKeyword(l_hardwareFlag, l_vpdPath, l_recordName,
                           l_keywordName, l_filePath);
    }

    if (!l_writeFlag->empty())
    {
        if ((l_keywordValueOption->empty() && l_fileOption->empty()) ||
            (!l_keywordValueOption->empty() && !l_fileOption->empty()))
        {
            std::cerr
                << "Please provide keyword value.\nUse --value/--file to give "
                   "keyword value. Refer --help."
                << std::endl;
            return vpd::constants::FAILURE;
        }

        if (!l_fileOption->empty())
        {
            l_keywordValue = vpd::utils::readValueFromFile(l_filePath);
            if (l_keywordValue.empty())
            {
                return vpd::constants::FAILURE;
            }

            return writeKeyword(l_hardwareFlag, l_fileOption, l_vpdPath,
                                l_recordName, l_keywordName, l_keywordValue);
        }

        return writeKeyword(l_hardwareFlag, l_keywordValueOption, l_vpdPath,
                            l_recordName, l_keywordName, l_keywordValue);
    }

    if (!l_dumpObjFlag->empty())
    {
        vpd::VpdTool l_vpdToolObj;
        return l_vpdToolObj.dumpObject(l_vpdPath);
    }

    if (!l_fixSystemVpdFlag->empty())
    {
        vpd::VpdTool l_vpdToolObj;
        return l_vpdToolObj.fixSystemVpd();
    }

    if (!l_mfgCleanFlag->empty())
    {
        return doMfgClean(l_mfgCleanConfirmFlag,
                          l_mfgCleanSyncBiosAttributesFlag);
    }

    if (!l_dumpInventoryFlag->empty())
    {
        vpd::VpdTool l_vpdToolObj;
        return l_vpdToolObj.dumpInventory(!l_dumpInventoryTableFlag->empty());
    }

    if (!l_forceResetFlag->empty())
    {
        return forceReset();
    }

    std::cout << l_app.help() << std::endl;
    return vpd::constants::FAILURE;
}
