#include "sandbox.h"

#include "utils.h"
#include "backing.h"
#include "container.h"
#include "domain.h"

#include <stdio.h>
#include <stdbool.h>
#include <pwd.h>
#include <unistd.h>

#define ALIAS(...) \
	(const char*[]) { __VA_ARGS__, NULL }

#define ALIASES(...) \
	(const char**[]) { __VA_ARGS__, NULL }

#define ARGUMENTS(...)   \
	(const Argument[]) { \
		__VA_ARGS__, {}  \
	}

#define OPTIONS(...)    \
	(const Option[]) {  \
		__VA_ARGS__, {} \
	}

Command COMMANDS[] = {
	// Help
	{
		.handler = command_help,
		.description = "Display help information.",
		.details = "Display help information about the available commands and their options.",
		.aliases = ALIASES(ALIAS("help")),
		.arguments = ARGUMENTS({.name = "command", .required = false, .description = "The command to display help information for."},
							   {.name = "test", .required = false, .description = "Test."}),
		.options = OPTIONS({.aliases = ALIASES(ALIAS("--help"), ALIAS("-h")), .arguments = NULL, .description = "Display help information."},
						   {.aliases = ALIASES(ALIAS("--test")), .arguments = NULL, .description = "Test."}),
	},
};

int main(int argc, char** argv) {
	// Ensure the sandbox user exists
	struct passwd* pw = getpwnam(SANDBOX_USER);
	if (pw == NULL) {
		fprintf(stderr, "User '%s' does not exist. Please check that the program is installed correctly.\n", SANDBOX_USER);
		return EXIT_FAILURE;
	}

	// Check that the program is either run as root or as the sandbox user
	if (geteuid() != 0 && geteuid() != pw->pw_uid) {
		fprintf(stderr, "This program must be run as root or as the user '%s'.\n", SANDBOX_USER);
		return EXIT_FAILURE;
	}

	// If the program is run as root, switch to the sandbox user
	if (geteuid() == 0) {
		if (setregid(pw->pw_gid, pw->pw_gid) != 0) {
			fprintf(stderr, "Failed to switch to the group '%s'.\n", pw->pw_name);
			return EXIT_FAILURE;
		}

		if (setreuid(pw->pw_uid, pw->pw_uid) != 0) {
			fprintf(stderr, "Failed to switch to the user '%s'.\n", pw->pw_name);
			return EXIT_FAILURE;
		}
	}

	// TODO: Parse commands from the command line
	return EXIT_SUCCESS;
}

int command_help(int argc, char* argv[]) {
	return EXIT_SUCCESS;
}