#include "sandbox.h"

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

#include <stdio.h>
#include <stdbool.h>
#include <pwd.h>
#include <unistd.h>
#include <string.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__, {} \
	}

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

const Command COMMANDS[] = {
	{
		.handler = command_help,
		.description = "Display help information",
		.details = "Display help information for a specific command",

		.aliases = ALIASES(ALIAS("h"), ALIAS("help", "me")),
		.arguments = ARGUMENTS({
			.name = "command",
			.description = "The command to display help information for",
			.optional = true,
		}),
		.options = OPTIONS({
			.aliases = OPTION_ALIASES("verbose", "v"),
			.description = "Display verbose help information",
			.arguments = ARGUMENTS({
				.name = "level",
				.description = "The level of verbosity to display",
			}),
		}),
	},
	{}};

int main(int argc, char** argv) {
	if (argc == 1) {
		// Handle no command
		fprintf(stderr, "No command specified\n");
		return EXIT_FAILURE;
	}

	// For each command
	for (int i = 0; COMMANDS[i].handler != NULL; i++) {
		const Command* command = &COMMANDS[i];

		// For each alias
		bool command_matched = false;
		int k = 0;
		for (int j = 0; command->aliases[j] != NULL; j++) {
			const char** alias = command->aliases[j];

			// For each string in the alias
			bool alias_matched = true;
			for (k = 0; alias[k] != NULL; k++)
				if (argc <= 1 + k || strcmp(argv[1 + k], alias[k]) != 0) {
					alias_matched = false;
					break;
				}

			// Check if the alias matched
			if (alias_matched) {
				command_matched = true;
				break;
			}
		}

		// If the command matched
		if (command_matched) {
			// Call the command handler
			return command->handler(argc - 1 - k, argv + 1 + k);
		}
	}

	fprintf(stderr, "Unknown command: ");
	for (int i = 1; i < argc; i++)
		fprintf(stderr, "%s ", argv[i]);
	fprintf(stderr, "\n");

	return EXIT_FAILURE;
}

int command_help(int argc, char* argv[]) {
	// Print argv
	printf("argc: %d\n", argc);
	for (int i = 0; i < argc; i++)
		printf("%s\n", argv[i]);

	return EXIT_SUCCESS;
}