#include "MigrationRunner.h"

#include "GeneralUtils.h"

#include <fstream>
#include <algorithm>
#include <thread>

void MigrationRunner::RunMigrations() {
	auto stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());");
	stmt->executeQuery();
	delete stmt;

	sql::SQLString finalSQL = "";
	Migration checkMigration{};

	for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/")) {
		auto migration = LoadMigration(entry);

		if (migration.data.empty()) {
			continue;
		}

		checkMigration = migration;

		stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;");
		stmt->setString(1, migration.name);
		auto res = stmt->executeQuery();
		bool doExit = res->next();
		delete res;
		delete stmt;
		if (doExit) continue;

		Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str());

		finalSQL.append(migration.data);
		finalSQL.append('\n');

		stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);");
		stmt->setString(1, entry);
		stmt->execute();
		delete stmt;
	}

	if (!finalSQL.empty()) {
		try {
			auto simpleStatement = Database::CreateStmt();
			simpleStatement->execute(finalSQL);
			delete simpleStatement;
		} catch (sql::SQLException e) {
			Game::logger->Log("MigrationRunner", "Encountered error running migration: %s", e.what());
		}
	}
}

Migration MigrationRunner::LoadMigration(std::string path) {
	Migration migration{};
	std::ifstream file("./migrations/" + path);

	if (file.is_open()) {
		std::hash<std::string> hash;

		std::string line;
		std::string total = "";

		while (std::getline(file, line)) {
			total += line;
		}

		file.close();

		migration.name = path;
		migration.data = total;
	}

	return migration;
}
