#include "config.h"

#include "msl_verify.hpp"

#include <phosphor-logging/log.hpp>

#include <filesystem>
#include <fstream>
#include <regex>

namespace openpower
{
namespace software
{
namespace image
{

using namespace phosphor::logging;
using AssociationList =
    std::vector<std::tuple<std::string, std::string, std::string>>;

int MinimumShipLevel::compare(const Version& a, const Version& b)
{
    if (a.major < b.major)
    {
        return -1;
    }
    else if (a.major > b.major)
    {
        return 1;
    }

    if (a.minor < b.minor)
    {
        return -1;
    }
    else if (a.minor > b.minor)
    {
        return 1;
    }

    if (a.rev < b.rev)
    {
        return -1;
    }
    else if (a.rev > b.rev)
    {
        return 1;
    }

    return 0;
}

void MinimumShipLevel::parse(const std::string& versionStr, Version& version)
{
    std::smatch match;
    version = {0, 0, 0};

    // Match for vX.Y.Z or v-X.Y.Z
    std::regex regex{"v-?([0-9]+)\\.([0-9]+)\\.([0-9]+)", std::regex::extended};

    if (!std::regex_search(versionStr, match, regex))
    {
        // Match for vX.Y or v-X.Y
        std::regex regexShort{"v-?([0-9]+)\\.([0-9]+)", std::regex::extended};
        if (!std::regex_search(versionStr, match, regexShort))
        {
            log<level::ERR>("Unable to parse PNOR version",
                            entry("VERSION=%s", versionStr.c_str()));
            return;
        }
    }
    else
    {
        // Populate Z
        version.rev = std::stoi(match[3]);
    }
    version.major = std::stoi(match[1]);
    version.minor = std::stoi(match[2]);
}

std::string MinimumShipLevel::getFunctionalVersion()
{
    auto bus = sdbusplus::bus::new_default();
    auto method = bus.new_method_call(BUSNAME_UPDATER, SOFTWARE_OBJPATH,
                                      SYSTEMD_PROPERTY_INTERFACE, "Get");
    method.append(ASSOCIATIONS_INTERFACE, "Associations");
    auto response = bus.call(method);

    std::variant<AssociationList> associations;
    try
    {
        response.read(associations);
    }
    catch (const sdbusplus::exception::exception& e)
    {
        log<level::ERR>("Failed to read software associations",
                        entry("ERROR=%s", e.what()),
                        entry("SIGNATURE=%s", response.get_signature()));
        return {};
    }

    auto& assocs = std::get<AssociationList>(associations);
    if (assocs.empty())
    {
        return {};
    }

    for (const auto& assoc : assocs)
    {
        if (std::get<0>(assoc).compare(FUNCTIONAL_FWD_ASSOCIATION) == 0)
        {
            auto path = std::get<2>(assoc);
            method = bus.new_method_call(BUSNAME_UPDATER, path.c_str(),
                                         SYSTEMD_PROPERTY_INTERFACE, "Get");
            method.append(VERSION_IFACE, "Version");
            response = bus.call(method);

            std::variant<std::string> functionalVersion;
            try
            {
                response.read(functionalVersion);
                return std::get<std::string>(functionalVersion);
            }
            catch (const sdbusplus::exception::exception& e)
            {
                log<level::ERR>(
                    "Failed to read version property",
                    entry("ERROR=%s", e.what()),
                    entry("SIGNATURE=%s", response.get_signature()));
                return {};
            }
        }
    }

    return {};
}

bool MinimumShipLevel::verify()
{
    if (minShipLevel.empty())
    {
        return true;
    }

    auto actual = getFunctionalVersion();
    if (actual.empty())
    {
        return true;
    }

    // Multiple min versions separated by a space can be specified, parse them
    // into a vector, then sort them in ascending order
    std::istringstream minStream(minShipLevel);
    std::vector<std::string> mins(std::istream_iterator<std::string>{minStream},
                                  std::istream_iterator<std::string>());
    std::sort(mins.begin(), mins.end());

    // In order to handle non-continuous multiple min versions, need to compare
    // the major.minor section first, then if they're the same, compare the rev.
    // Ex: the min versions specified are 2.0.10 and 2.2. We need to pass if
    // actual is 2.0.11 but fail if it's 2.1.x.
    // 1. Save off the rev number to compare later if needed.
    // 2. Zero out the rev number to just compare major and minor.
    Version actualVersion = {0, 0, 0};
    parse(actual, actualVersion);
    Version actualRev = {0, 0, actualVersion.rev};
    actualVersion.rev = 0;

    auto rc = 0;
    std::string tmpMin{};

    for (auto const& min : mins)
    {
        tmpMin = min;

        Version minVersion = {0, 0, 0};
        parse(min, minVersion);
        Version minRev = {0, 0, minVersion.rev};
        minVersion.rev = 0;

        rc = compare(actualVersion, minVersion);
        if (rc < 0)
        {
            break;
        }
        else if (rc == 0)
        {
            // Same major.minor version, compare the rev
            rc = compare(actualRev, minRev);
            break;
        }
    }
    if (rc < 0)
    {
        log<level::ERR>(
            "PNOR Mininum Ship Level NOT met",
            entry("MIN_VERSION=%s", tmpMin.c_str()),
            entry("ACTUAL_VERSION=%s", actual.c_str()),
            entry("VERSION_PURPOSE=%s",
                  "xyz.openbmc_project.Software.Version.VersionPurpose.Host"));
        return false;
    }

    return true;
}

} // namespace image
} // namespace software
} // namespace openpower
