#include "config.h"

#include "version.hpp"

#include "xyz/openbmc_project/Common/error.hpp"

#include <openssl/evp.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/lg2.hpp>

#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

namespace phosphor
{
namespace software
{
namespace manager
{

PHOSPHOR_LOG2_USING;
using namespace phosphor::logging;
using Argument = xyz::openbmc_project::Common::InvalidArgument;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

std::string Version::getValue(const std::string& manifestFilePath,
                              std::string key)
{
    std::vector<std::string> values = getRepeatedValues(manifestFilePath, key);
    if (values.empty())
    {
        return std::string{};
    }
    if (values.size() > 1)
    {
        error("Multiple values found in MANIFEST file for key: {KEY}", "KEY",
              key);
    }
    return values.at(0);
}

std::vector<std::string>
    Version::getRepeatedValues(const std::string& manifestFilePath,
                               std::string key)
{
    key = key + "=";
    auto keySize = key.length();

    if (manifestFilePath.empty())
    {
        error("ManifestFilePath is empty.");
        elog<InvalidArgument>(
            Argument::ARGUMENT_NAME("manifestFilePath"),
            Argument::ARGUMENT_VALUE(manifestFilePath.c_str()));
    }

    std::vector<std::string> values{};
    std::ifstream efile;
    std::string line;
    efile.exceptions(std::ifstream::failbit | std::ifstream::badbit);

    // Too many GCC bugs (53984, 66145) to do this the right way...
    try
    {
        efile.open(manifestFilePath);
        while (getline(efile, line))
        {
            if (!line.empty() && line.back() == '\r')
            {
                // If the manifest has CRLF line terminators, e.g. is created on
                // Windows, the line will contain \r at the end, remove it.
                line.pop_back();
            }
            if (line.compare(0, keySize, key) == 0)
            {
                values.push_back(line.substr(keySize));
            }
        }
        efile.close();
    }
    catch (const std::exception& e)
    {
        if (!efile.eof())
        {
            error("Error occurred when reading MANIFEST file: {ERROR}", "KEY",
                  key, "ERROR", e);
        }
    }

    if (values.empty())
    {
        info("No values found in MANIFEST file for key: {KEY}", "KEY", key);
    }

    return values;
}

using EVP_MD_CTX_Ptr =
    std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;

std::string Version::getId(const std::string& version)
{

    if (version.empty())
    {
        error("Version is empty.");
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Version"),
                              Argument::ARGUMENT_VALUE(version.c_str()));
    }

    std::array<unsigned char, EVP_MAX_MD_SIZE> digest{};
    EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_new(), &::EVP_MD_CTX_free);

    EVP_DigestInit(ctx.get(), EVP_sha512());
    EVP_DigestUpdate(ctx.get(), version.c_str(), strlen(version.c_str()));
    EVP_DigestFinal(ctx.get(), digest.data(), nullptr);

    // We are only using the first 8 characters.
    char mdString[9];
    snprintf(mdString, sizeof(mdString), "%02x%02x%02x%02x",
             (unsigned int)digest[0], (unsigned int)digest[1],
             (unsigned int)digest[2], (unsigned int)digest[3]);

    return mdString;
}

std::string Version::getBMCMachine(const std::string& releaseFilePath)
{
    std::string machineKey = "OPENBMC_TARGET_MACHINE=";
    std::string machine{};
    std::ifstream efile(releaseFilePath);
    std::string line;

    while (getline(efile, line))
    {
        if (line.substr(0, machineKey.size()).find(machineKey) !=
            std::string::npos)
        {
            std::size_t pos = line.find_first_of('"') + 1;
            machine = line.substr(pos, line.find_last_of('"') - pos);
            break;
        }
    }

    if (machine.empty())
    {
        error("Unable to find OPENBMC_TARGET_MACHINE");
        elog<InternalFailure>();
    }

    return machine;
}

std::string Version::getBMCExtendedVersion(const std::string& releaseFilePath)
{
    std::string extendedVersionKey = "EXTENDED_VERSION=";
    std::string extendedVersionValue{};
    std::string extendedVersion{};
    std::ifstream efile(releaseFilePath);
    std::string line;

    while (getline(efile, line))
    {
        if (line.substr(0, extendedVersionKey.size())
                .find(extendedVersionKey) != std::string::npos)
        {
            extendedVersionValue = line.substr(extendedVersionKey.size());
            std::size_t pos = extendedVersionValue.find_first_of('"') + 1;
            extendedVersion = extendedVersionValue.substr(
                pos, extendedVersionValue.find_last_of('"') - pos);
            break;
        }
    }

    return extendedVersion;
}

std::string Version::getBMCVersion(const std::string& releaseFilePath)
{
    std::string versionKey = "VERSION_ID=";
    std::string versionValue{};
    std::string version{};
    std::ifstream efile;
    std::string line;
    efile.open(releaseFilePath);

    while (getline(efile, line))
    {
        if (line.substr(0, versionKey.size()).find(versionKey) !=
            std::string::npos)
        {
            // Support quoted and unquoted values
            // 1. Remove the versionKey so that we process the value only.
            versionValue = line.substr(versionKey.size());

            // 2. Look for a starting quote, then increment the position by 1 to
            //    skip the quote character. If no quote is found,
            //    find_first_of() returns npos (-1), which by adding +1 sets pos
            //    to 0 (beginning of unquoted string).
            std::size_t pos = versionValue.find_first_of('"') + 1;

            // 3. Look for ending quote, then decrease the position by pos to
            //    get the size of the string up to before the ending quote. If
            //    no quote is found, find_last_of() returns npos (-1), and pos
            //    is 0 for the unquoted case, so substr() is called with a len
            //    parameter of npos (-1) which according to the documentation
            //    indicates to use all characters until the end of the string.
            version =
                versionValue.substr(pos, versionValue.find_last_of('"') - pos);
            break;
        }
    }
    efile.close();

    if (version.empty())
    {
        error("BMC current version is empty");
        elog<InternalFailure>();
    }

    return version;
}

void Delete::delete_()
{
    if (parent.eraseCallback)
    {
        parent.eraseCallback(parent.id);
    }
}

} // namespace manager
} // namespace software
} // namespace phosphor
