#include <systemd_target_parser.hpp>
#include <gtest/gtest.h>

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <filesystem>

namespace fs = std::filesystem;

// Enable debug by default for debug when needed
bool gVerbose = true;

TEST(TargetJsonParser, BasicGoodPath)
{
    auto defaultData1 = R"(
        {
            "targets" : {
                "multi-user.target" : {
                    "errorsToMonitor": ["default"],
                    "errorToLog": "xyz.openbmc_project.State.BMC.Error.MultiUserTargetFailure"},
                "obmc-chassis-poweron@0.target" : {
                    "errorsToMonitor": ["timeout", "failed"],
                    "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
                }
        }
    )"_json;

    auto defaultData2 = R"(
        {
            "targets" : {
                "obmc-host-start@0.target" : {
                    "errorsToMonitor": ["default"],
                    "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStartFailure"},
                "obmc-host-stop@0.target" : {
                    "errorsToMonitor": ["dependency"],
                    "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStopFailure"}
                }
        }
    )"_json;

    std::FILE* tmpf = fopen("/tmp/good_file1.json", "w");
    std::fputs(defaultData1.dump().c_str(), tmpf);
    std::fclose(tmpf);

    tmpf = fopen("/tmp/good_file2.json", "w");
    std::fputs(defaultData2.dump().c_str(), tmpf);
    std::fclose(tmpf);

    std::vector<std::string> filePaths;
    filePaths.push_back("/tmp/good_file1.json");
    filePaths.push_back("/tmp/good_file2.json");

    TargetErrorData targetData = parseFiles(filePaths);

    EXPECT_EQ(targetData.size(), 4);
    EXPECT_NE(targetData.find("multi-user.target"), targetData.end());
    EXPECT_NE(targetData.find("obmc-chassis-poweron@0.target"),
              targetData.end());
    EXPECT_NE(targetData.find("obmc-host-start@0.target"), targetData.end());
    EXPECT_NE(targetData.find("obmc-host-stop@0.target"), targetData.end());
    targetEntry tgt = targetData["obmc-chassis-poweron@0.target"];
    EXPECT_EQ(tgt.errorToLog,
              "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure");
    EXPECT_EQ(tgt.errorsToMonitor.size(), 2);
    // Check a target with "default" for errorsToMonitor, should have 3 defaults
    tgt = targetData["obmc-host-start@0.target"];
    EXPECT_EQ(tgt.errorsToMonitor.size(), 3);

    std::remove("/tmp/good_file1.json");
    std::remove("/tmp/good_file2.json");
}

TEST(TargetJsonParser, InvalidErrorToMonitor)
{
    auto invalidDataError = R"(
        {
            "targets" : {
                "obmc-chassis-poweron@0.target" : {
                    "errorsToMonitor": ["timeout", "invalid"],
                    "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
                }
        }
    )"_json;

    std::FILE* tmpf = fopen("/tmp/invalid_error_file.json", "w");
    std::fputs(invalidDataError.dump().c_str(), tmpf);
    std::fclose(tmpf);

    std::vector<std::string> filePaths;
    filePaths.push_back("/tmp/invalid_error_file.json");

    // Verify exception thrown on invalid errorsToMonitor
    EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
                 std::out_of_range);
    std::remove("/tmp/invalid_error_file.json");
}

TEST(TargetJsonParser, InvalidFileFormat)
{
    std::FILE* tmpf = fopen("/tmp/invalid_json_file.json", "w");
    std::fputs("{\"targets\":{\"missing closing quote}}", tmpf);
    fclose(tmpf);

    std::vector<std::string> filePaths;
    filePaths.push_back("/tmp/invalid_json_file.json");

    // Verify exception thrown on invalid json file format
    EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
                 nlohmann::detail::parse_error);
    std::remove("/tmp/invalid_json_file.json");
}

TEST(TargetJsonParser, NotJustDefault)
{
    auto notJustDefault = R"(
        {
            "targets" : {
                "obmc-chassis-poweron@0.target" : {
                    "errorsToMonitor": ["timeout", "default"],
                    "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
                }
        }
    )"_json;

    std::FILE* tmpf = fopen("/tmp/not_just_default_file.json", "w");
    std::fputs(notJustDefault.dump().c_str(), tmpf);
    std::fclose(tmpf);

    std::vector<std::string> filePaths;
    filePaths.push_back("/tmp/not_just_default_file.json");

    // Verify exception thrown on invalid errorsToMonitor
    EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
                 std::invalid_argument);
    std::remove("/tmp/not_just_default_file.json");
}
