#include <Utils.hpp>

#include <filesystem>
#include <fstream>

#include <gtest/gtest.h>

namespace fs = std::filesystem;
class TestUtils : public testing::Test
{
  public:
    std::string testDir;
    fs::path hwmonDir;
    fs::path peciDir;
    TestUtils()
    {
        // Create test environment
        char dir[] = "./testDirXXXXXX";
        testDir = mkdtemp(dir);

        if (testDir.empty())
        {
            throw std::bad_alloc();
        }
        hwmonDir = fs::path(testDir) / "hwmon";
        fs::create_directory(hwmonDir);
        auto hwmon10 = hwmonDir / "hwmon10";
        fs::create_directory(hwmonDir / "hwmon10");
        std::ofstream{hwmon10 / "temp1_input"};
        std::ofstream{hwmon10 / "temp1_min"};
        std::ofstream{hwmon10 / "temp1_max"};
        std::ofstream{hwmon10 / "temp2_input"};
        createPECIDir();
    }

    ~TestUtils() override
    {
        fs::remove_all(testDir);
    }

    void createPECIDir()
    {
        peciDir = fs::path(testDir) / "peci";
        auto peci0 =
            peciDir / "peci-0/device/0-30/peci-cputemp.0/hwmon/hwmon25";
        fs::create_directories(peci0);
        std::ofstream{peci0 / "temp0_input"};
        std::ofstream{peci0 / "temp1_input"};
        std::ofstream{peci0 / "temp2_input"};
        std::ofstream{peci0 / "name"};
        auto devDir = peciDir / "peci-0/peci_dev/peci-0";
        fs::create_directories(devDir);
        fs::create_directory_symlink("../../../peci-0", devDir / "device");
        fs::create_directory_symlink("device/0-30", peciDir / "peci-0/0-30");

        // Let's keep this for debugging purpose
        for (auto p = fs::recursive_directory_iterator(
                 peciDir, fs::directory_options::follow_directory_symlink);
             p != fs::recursive_directory_iterator(); ++p)
        {
            std::string path = p->path().string();
            fprintf(stderr, "%s\n", path.c_str());
            if (p.depth() >= 6)
            {
                p.disable_recursion_pending();
            }
        }
    }
};

TEST_F(TestUtils, findFiles_non_exist)
{
    std::vector<fs::path> foundPaths;
    auto ret = findFiles("non-exist", "", foundPaths);

    EXPECT_FALSE(ret);
    EXPECT_TRUE(foundPaths.empty());
}

TEST_F(TestUtils, findFiles_in_hwmon_no_match)
{
    std::vector<fs::path> foundPaths;
    auto ret = findFiles(hwmonDir, R"(in\d+_input)", foundPaths);

    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 0u);
}

TEST_F(TestUtils, findFiles_in_hwmon_match)
{
    std::vector<fs::path> foundPaths;
    auto ret = findFiles(hwmonDir, R"(temp\d+_input)", foundPaths);

    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 2u);
}

TEST_F(TestUtils, findFiles_in_peci_no_match)
{
    std::vector<fs::path> foundPaths;
    auto ret =
        findFiles(peciDir, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/aaa$)",
                  foundPaths, 6);

    EXPECT_TRUE(ret);
    EXPECT_TRUE(foundPaths.empty());
}

TEST_F(TestUtils, findFiles_in_peci_match)
{
    std::vector<fs::path> foundPaths;
    auto ret =
        findFiles(peciDir, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
                  foundPaths, 6);
    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 1u);

    foundPaths.clear();

    ret = findFiles(peciDir,
                    R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
                    foundPaths, 6);
    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 3u);
}

TEST_F(TestUtils, findFiles_hwmonPath_end_with_slash)
{
    std::string p = hwmonDir.string() + "/";
    std::vector<fs::path> foundPaths;
    auto ret = findFiles(p, R"(temp\d+_input)", foundPaths);

    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 2u);
}

TEST_F(TestUtils, findFiles_peciPath_end_with_slash)
{
    std::string p = peciDir.string() + "/";
    std::vector<fs::path> foundPaths;
    auto ret =
        findFiles(p, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
                  foundPaths, 6);

    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 3u);
}

TEST_F(TestUtils, findFiles_in_sub_peci_match)
{
    std::vector<fs::path> foundPaths;
    auto ret =
        findFiles(peciDir / "peci-0", R"(\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
                  foundPaths, 5);
    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 1u);

    foundPaths.clear();

    ret = findFiles(peciDir / "peci-0",
                    R"(\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
                    foundPaths, 5);
    EXPECT_TRUE(ret);
    EXPECT_EQ(foundPaths.size(), 3u);
}
