#include "command.h"

#include "sandbox.h"

#include <stdio.h>
#include <string.h>

Command COMMANDS[] = {
	{"help", "[command]", "Shows help for all or a specific command.", CMD_HELP},
	{"version", "", "Shows the version of the program.", CMD_VERSION},
	{NULL},
	{"add-entry", "<entry> [--root|-r <size>] [--backing|-b <backing>]", "Adds a new entry to the pool", CMD_ADD_ENTRY},
	{"remove-entry", "<entry>", "Removes an entry from the pool", CMD_REMOVE_ENTRY},
	{"list-entries", "", "Lists all entries in the pool", CMD_LIST_ENTRIES},
	{"clear-entries", "", "Clears all entries from the pool", CMD_CLEAR_ENTRIES},
	{NULL},
	{"add-backing", "<entry>", "Adds a backing disk to the pool from the given entry", CMD_ADD_BACKING},
	{"remove-backing", "<backing>", "Removes a backing disk from the pool", CMD_REMOVE_BACKING},
	{"list-backings", "[--tree|-t]", "Lists all backing disks in the pool", CMD_LIST_BACKINGS},
	{"clear-backings", "", "Clears all backing disks from the pool", CMD_CLEAR_BACKINGS},
	{NULL},
	{"start", "<entry> [--no-pci] [--vnc <port> <password>] [--iso <iso>]", "Starts the sandbox with the given entry", CMD_START},
	{"power", "", "Sends a power signal to the sandbox", CMD_POWER},
	{"stop", "[--force|-f] [--timeout|-t <timeout>]", "Stops the sandbox", CMD_STOP},
	{"status", "", "Shows the status of the sandbox", CMD_STATUS},
};

Command* find_command(const char* name) {
	Command* match = NULL;

	// Find all matching commands (starting with the given name)
	size_t length = strlen(name);
	for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) {
		if (COMMANDS[i].name == NULL)
			continue;

		// Check the sizes
		if (strlen(COMMANDS[i].name) < length)
			continue;

		if (strncmp(name, COMMANDS[i].name, length) == 0) {
			// Check for multiple matches
			if (match != NULL)
				return NULL;

			match = &COMMANDS[i];
		}
	}

	return match;
}

void show_help() {
	printf("Usage: sandbox <command> [args]\n\n");
	printf("Commands:\n");
	for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) {
		if (COMMANDS[i].name == NULL) {
			printf("\n");
			continue;
		}

		printf("    %s %s\n", COMMANDS[i].name, COMMANDS[i].args);
		printf("        %s\n", COMMANDS[i].description);
	}
	printf("\n");
	printf("For more information about a specific command, use 'sandbox help <command>'.\n");
}

void show_command_help(const Command* command) {
	printf("Usage: sandbox %s %s\n", command->name, command->args);
	printf("   %s\n", command->description);
}

int cmd_help(int argc, char** argv) {
	if (argc == 0) {
		show_help();
		return 0;
	}

	Command* command = find_command(argv[0]);
	if (command == NULL) {
		printf("Unknown command '%s'.\n", argv[0]);
		return 1;
	}

	show_command_help(command);
	return 0;
}

int cmd_version(int argc, char** argv) {
	printf("Sandbox version v" SANDBOX_VERSION "\n");
	return 0;
}