#include "config.h"

#include "utils.hpp"

#include <openssl/evp.h>

#include <phosphor-logging/log.hpp>

#include <algorithm>
#include <fstream>
#include <sstream>

using namespace phosphor::logging;

namespace utils
{

namespace // anonymous
{
constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
} // namespace

namespace internal
{
template <typename... Ts>
std::string concat_string(const Ts&... ts)
{
    std::stringstream s;
    ((s << ts << " "), ...) << std::endl;
    return s.str();
}

// Helper function to run command
// Returns return code and the stdout
template <typename... Ts>
std::pair<int, std::string> exec(const Ts&... ts)
{
    std::array<char, 512> buffer;
    std::string cmd = concat_string(ts...);
    std::stringstream result;
    int rc;
    FILE* pipe = popen(cmd.c_str(), "r");
    if (!pipe)
    {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
    {
        result << buffer.data();
    }
    rc = pclose(pipe);
    return {rc, result.str()};
}

} // namespace internal
const UtilsInterface& getUtils()
{
    static Utils utils;
    return utils;
}

std::vector<std::string> Utils::getPSUInventoryPath(sdbusplus::bus_t& bus) const
{
    std::vector<std::string> paths;
    try
    {
        auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
                                          MAPPER_INTERFACE, "GetSubTreePaths");
        method.append(PSU_INVENTORY_PATH_BASE);
        method.append(0); // Depth 0 to search all
        method.append(std::vector<std::string>({PSU_INVENTORY_IFACE}));
        auto reply = bus.call(method);

        reply.read(paths);
    }
    catch (const sdbusplus::exception_t&)
    {
        // Inventory base path not there yet.
    }
    return paths;
}

std::string Utils::getService(sdbusplus::bus_t& bus, const char* path,
                              const char* interface) const
{
    auto services = getServices(bus, path, interface);
    if (services.empty())
    {
        return {};
    }
    return services[0];
}

std::vector<std::string> Utils::getServices(
    sdbusplus::bus_t& bus, const char* path, const char* interface) const
{
    auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
                                      MAPPER_INTERFACE, "GetObject");

    mapper.append(path, std::vector<std::string>({interface}));
    try
    {
        auto mapperResponseMsg = bus.call(mapper);

        std::vector<std::pair<std::string, std::vector<std::string>>>
            mapperResponse;
        mapperResponseMsg.read(mapperResponse);
        if (mapperResponse.empty())
        {
            log<level::ERR>("Error reading mapper response");
            throw std::runtime_error("Error reading mapper response");
        }
        std::vector<std::string> ret;
        for (const auto& i : mapperResponse)
        {
            ret.emplace_back(i.first);
        }
        return ret;
    }
    catch (const sdbusplus::exception_t& ex)
    {
        log<level::ERR>("GetObject call failed", entry("PATH=%s", path),
                        entry("INTERFACE=%s", interface));
        throw std::runtime_error("GetObject call failed");
    }
}

std::string Utils::getVersionId(const std::string& version) const
{
    if (version.empty())
    {
        log<level::ERR>("Error version is empty");
        return {};
    }

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

    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);

    // Only need 8 hex digits.
    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 Utils::getVersion(const std::string& inventoryPath) const
{
    // Invoke vendor-specify tool to get the version string, e.g.
    //   psutils get-version
    //   /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0
    auto [rc, r] = internal::exec(PSU_VERSION_UTIL, inventoryPath);
    return (rc == 0) ? r : "";
}

std::string Utils::getLatestVersion(const std::set<std::string>& versions) const
{
    if (versions.empty())
    {
        return {};
    }
    std::stringstream args;
    for (const auto& s : versions)
    {
        args << s << " ";
    }
    auto [rc, r] = internal::exec(PSU_VERSION_COMPARE_UTIL, args.str());
    return (rc == 0) ? r : "";
}

bool Utils::isAssociated(const std::string& psuInventoryPath,
                         const AssociationList& assocs) const
{
    return std::find_if(assocs.begin(), assocs.end(),
                        [&psuInventoryPath](const auto& assoc) {
                            return psuInventoryPath == std::get<2>(assoc);
                        }) != assocs.end();
}

any Utils::getPropertyImpl(sdbusplus::bus_t& bus, const char* service,
                           const char* path, const char* interface,
                           const char* propertyName) const
{
    auto method = bus.new_method_call(service, path,
                                      "org.freedesktop.DBus.Properties", "Get");
    method.append(interface, propertyName);
    try
    {
        PropertyType value{};
        auto reply = bus.call(method);
        reply.read(value);
        return any(value);
    }
    catch (const sdbusplus::exception_t& ex)
    {
        log<level::ERR>("GetProperty call failed", entry("PATH=%s", path),
                        entry("INTERFACE=%s", interface),
                        entry("PROPERTY=%s", propertyName));
        throw std::runtime_error("GetProperty call failed");
    }
}

} // namespace utils
