#include "version.hpp"

#include "item_updater.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

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

namespace phosphor
{
namespace software
{
namespace updater
{

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

std::map<std::string, std::string> Version::getValues(
    const std::string& filePath, const std::vector<std::string>& keys)
{
    if (filePath.empty())
    {
        log<level::ERR>("Error filePath is empty");
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("FilePath"),
                              Argument::ARGUMENT_VALUE(filePath.c_str()));
    }

    std::ifstream efile(filePath);
    std::string line;
    std::map<std::string, std::string> ret;

    while (getline(efile, line))
    {
        if (!line.empty() && line.back() == '\r')
        {
            // Remove \r from the end of line
            line.pop_back();
        }
        for (const auto& key : keys)
        {
            auto value = key + "=";
            auto keySize = value.length();
            if (line.compare(0, keySize, value) == 0)
            {
                ret.emplace(key, line.substr(keySize));
                break;
            }
        }
    }
    return ret;
}

std::string Version::getValue(const std::string& filePath,
                              const std::string& key)
{
    std::string ret;
    auto values = Version::getValues(filePath, {key});
    const auto it = values.find(key);
    if (it != values.end())
    {
        ret = it->second;
    }
    return ret;
}

std::map<std::string, std::string>
    Version::getExtVersionInfo(const std::string& extVersion)
{
    // The extVersion shall be key/value pairs separated by comma,
    // e.g. key1=value1,key2=value2
    std::map<std::string, std::string> result;
    std::stringstream ss(extVersion);

    while (ss.good())
    {
        std::string substr;
        getline(ss, substr, ',');
        auto pos = substr.find('=');
        if (pos != std::string::npos)
        {
            std::string key = substr.substr(0, pos);
            std::string value = substr.substr(pos + 1);
            result.emplace(key, value);
        }
    }
    return result;
}

void Delete::delete_()
{
    if (version.eraseCallback)
    {
        version.eraseCallback(version.getVersionId());
    }
}

} // namespace updater
} // namespace software
} // namespace phosphor
