#include "hwmon_ffdc.hpp"

#include "logging.hpp"

#include <array>
#include <filesystem>
#include <format>
#include <fstream>
#include <string>
#include <vector>

namespace phosphor::fan::monitor
{

namespace util
{

namespace fs = std::filesystem;

inline std::vector<std::string> executeCommand(const std::string& command)
{
    std::vector<std::string> output;
    std::array<char, 128> buffer;

    auto pipe_close = [](auto fd) { (void)pclose(fd); };

    std::unique_ptr<FILE, decltype(pipe_close)> pipe(
        popen(command.c_str(), "r"), pipe_close);
    if (!pipe)
    {
        getLogger().log(
            std::format("popen() failed when running command: {}", command));
        return output;
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
    {
        output.emplace_back(buffer.data());
    }

    return output;
}

std::vector<std::string> getHwmonNameFFDC()
{
    const fs::path hwmonBaseDir{"/sys/class/hwmon"};
    std::vector<std::string> hwmonNames;

    if (!fs::exists(hwmonBaseDir))
    {
        getLogger().log(std::format("Hwmon base directory {} doesn't exist",
                                    hwmonBaseDir.native()));
        return hwmonNames;
    }

    try
    {
        for (const auto& path : fs::directory_iterator(hwmonBaseDir))
        {
            if (!path.is_directory())
            {
                continue;
            }

            auto nameFile = path.path() / "name";
            if (fs::exists(nameFile))
            {
                std::ifstream f{nameFile};
                if (f.good())
                {
                    std::string name;
                    f >> name;
                    hwmonNames.push_back(name);
                }
            }
        }
    }
    catch (const std::exception& e)
    {
        getLogger().log(
            std::format("Error traversing hwmon directories: {}", e.what()));
    }

    return hwmonNames;
}

std::vector<std::string> getDmesgFFDC()
{
    std::vector<std::string> output;
    auto dmesgOutput = executeCommand("dmesg");

    // Only pull in dmesg lines with interesting keywords.
    // One example is:
    // [   16.390603] max31785: probe of 7-0052 failed with error -110
    // using ' probe' to avoid 'modprobe'
    std::vector<std::string> matches{" probe", "failed"};

    for (const auto& line : dmesgOutput)
    {
        for (const auto& m : matches)
        {
            if (line.find(m) != std::string::npos)
            {
                output.push_back(line);
                if (output.back().back() == '\n')
                {
                    output.back().pop_back();
                }
                break;
            }
        }
    }

    return output;
}

} // namespace util

nlohmann::json collectHwmonFFDC()
{
    nlohmann::json ffdc;

    auto hwmonNames = util::getHwmonNameFFDC();
    if (!hwmonNames.empty())
    {
        ffdc["hwmonNames"] = std::move(hwmonNames);
    }

    auto dmesg = util::getDmesgFFDC();
    if (!dmesg.empty())
    {
        ffdc["dmesg"] = std::move(dmesg);
    }

    return ffdc;
}

} // namespace phosphor::fan::monitor
