/*
 * Tests for filesystem-touching functions in src/lib.cpp:
 *   get_max_cpu / set_max_cpu, process_directory, process_glob
 *
 * These tests create real temporary files/directories and clean them up
 * afterwards.  No test-framework fixtures are needed.
 */
#include <algorithm>
#include <vector>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#include "lib.h"
#include "test_framework.h"
#include "../test_helper.h"

/* Stub: defined in main.cpp, not linked here */
void (*ui_notify_user)(const std::string &) = nullptr;

/* ── get_max_cpu / set_max_cpu ──────────────────────────────────────────── */

static void test_set_get_max_cpu()
{
	int base = get_max_cpu();

	/* Larger value is accepted */
	set_max_cpu(base + 100);
	PT_ASSERT_EQ(get_max_cpu(), base + 100);

	/* Smaller value is ignored — _max_cpu only ever grows */
	set_max_cpu(base + 50);
	PT_ASSERT_EQ(get_max_cpu(), base + 100);

	/* Even larger value updates again */
	set_max_cpu(base + 200);
	PT_ASSERT_EQ(get_max_cpu(), base + 200);
}

/* ── process_directory ──────────────────────────────────────────────────── */

/* callback cannot capture — use a file-scope collector */
static std::vector<std::string> dir_entries;
static void collect_dir_entry(const std::string& name)
{
	dir_entries.push_back(name);
}

static void test_process_directory()
{
	char tmpdir[] = "/tmp/powertop_dir_XXXXXX";
	mkdtemp(tmpdir);
	std::string d(tmpdir);

	for (const char *name : {"alpha", "beta", "gamma"}) {
		int fd = open((d + "/" + name).c_str(), O_CREAT | O_WRONLY, 0644);
		close(fd);
	}

	dir_entries.clear();
	process_directory(d, collect_dir_entry);

	std::sort(dir_entries.begin(), dir_entries.end());
	PT_ASSERT_EQ(dir_entries.size(), (size_t)3);
	PT_ASSERT_EQ(dir_entries[0], "alpha");
	PT_ASSERT_EQ(dir_entries[1], "beta");
	PT_ASSERT_EQ(dir_entries[2], "gamma");

	for (const char *name : {"alpha", "beta", "gamma"})
		unlink((d + "/" + name).c_str());
	rmdir(tmpdir);
}

static void test_process_directory_nonexistent_is_silent()
{
	/* process_directory on a missing dir should simply do nothing */
	dir_entries.clear();
	process_directory("/tmp/powertop_no_such_dir_xyz", collect_dir_entry);
	PT_ASSERT_EQ(dir_entries.size(), (size_t)0);
}

/* ── main ───────────────────────────────────────────────────────────────── */

int main()
{
	std::cout << "=== get_max_cpu / set_max_cpu tests ===\n";
	PT_RUN_TEST(test_set_get_max_cpu);

	std::cout << "\n=== process_directory tests ===\n";
	PT_RUN_TEST(test_process_directory);
	PT_RUN_TEST(test_process_directory_nonexistent_is_silent);

	return pt_test_summary();
}
