/*\
|*|  Parity Archive - A way to restore missing files in a set.
|*|
|*|  Copyright (C) 2001  Willem Monsuwe (willem@stack.nl)
|*|
|*|  File format by Stefan Wehlus -
|*|   initial idea by Tobias Rieper, further suggestions by Kilroy Balore 
|*|
|*|  CommandLine User Interface
\*/

#include <stdio.h>

#include "interface.h"

/*\
|*| Print usage
\*/
static int
usage(void)
{
	printf(
"Usage:\n"
"   par c(heck)   [options] <par file>         : Check parity archive\n"
"   par r(ecover) [options] <par file>         : Restore missing volumes\n"
"   par a(dd)     [options] <par file> [files] : Add files to parity archive\n"
" Advanced:\n"
"   par m(ix)     [options] : Try to restore from all parity files at once\n"
"   par i(nteractive) [<par files>] : Interactive mode (very bare-bones)\n"
"\n"
"Options: (Can be turned off with '+')\n"
"    -m   : Move existing files out of the way\n"
"    -f   : Fix faulty filenames\n"
"    -p<n>: Number of files per parity volume\n"
" or -n<n>: Number of parity volumes to create\n"
"    -k   : Keep broken files\n"
"    -s   : Be smart if filenames are consistently different.\n"
"    +i   : Do not add following files to parity volumes\n"
"    +c   : Do not create parity volumes\n"
"    +C   : Ignore case in filename comparisons\n"
"    +H   : Do not check control hashes\n"
"    -v,+v: Increase or decrease verbosity\n"
"    -h,-?: Display this help\n"
"    --   : Always treat following arguments as files\n"
"\n"
	);
	return 0;
}

int
ui_cli(int argc, char *argv[])
{
	int nvolumes = 10, pervol = 1, adding = 1, makepxx = 1,
		smart = 0, dash = 0, plus = 0;
	int (* flag)(int) = par_setflags;

	par_setflags(PARFLAG_CTRL | PARFLAG_CASE | PARFLAG_MOVE);

	if (argc == 1) return usage();

	for (; argc > 1; argc--, argv++) {
		if (((argv[1][0] == '-') || (argv[1][0] == '+')) &&
		    argv[1][1] && !dash) {
			for (p = argv[1]; *p; p++) switch (*p) {
			case '-':
				if (p[1] == '-') {
					dash = 1;
				} else {
					plus = 1;
					flag = par_setflags;
				}
				break;
			case '+':
				plus = 0;
				flag = par_unsetflags;
				break;
			case 'm':
				flag(PARFLAG_MOVE);
				break;
			case 'i':
				cmd.add = plus;
				break;
			case 'f':
				cmd.fix = plus;
				break;
			case 'c':
				cmd.pxx = plus;
				break;
			case 'v':
				if (plus)
					cmd.loglevel++;
				else
					cmd.loglevel--;
				break;
			case 'p':
			case 'n':
				pervol = (*p == 'p');
				while (isspace(*++p))
					;
				if (!*p) {
					argv++;
					argc--;
					p = argv[1];
				}
				if (!isdigit(*p)) {
					fprintf(stderr, "Value expected!\n");
				} else {
					cmd.volumes = 0;
					do {
						cmd.volumes *= 10;
						cmd.volumes += *p - '0';
					} while (isdigit(*++p));
					p--;
				}
				break;
			case 'H':
				flag(PARFLAG_CTRL);
				break;
			case 'C':
				flag(PARFLAG_CASE);
				break;
			case 'k':
				flag(PARFLAG_KEEP);
				break;
			case 's':
				smart = plus;
				break;
			case '?':
			case 'h':
				return usage();
			default:
				fprintf(stderr,
					"Unknown switch: '%c'\n", *p);
				break;
			}
			continue;
		}
		if (!cmd.action) {
			switch (argv[1][0]) {
			case 'c':
			case 'C':
				cmd.action = ACTION_CHECK;
				break;
			case 'm':
			case 'M':
				cmd.action = ACTION_MIX;
				break;
			case 'r':
			case 'R':
				cmd.action = ACTION_RESTORE;
				break;
			case 'a':
			case 'A':
				cmd.action = ACTION_ADD;
				break;
			case 'i':
			case 'I':
				cmd.action = ACTION_TEXT_UI;
				break;
			default:
				fprintf(stderr, "Unknown command: '%s'\n",
						argv[1]);
				break;
			}
			continue;
		}
		switch (cmd.action) {
		default:
			cmd.action = ACTION_CHECK;
			/*\ FALLTHROUGH \*/
		case ACTION_CHECK:
		case ACTION_RESTORE:
			fprintf(stderr, "Checking %s\n", argv[1]);
			par = read_par_header(unist(argv[1]), 0, 0, 0);
			if (!par) {
				fail = 2;
				continue;
			}
			if (check_par(par) < 0) fail = 1;
			free_par(par);
			par = 0;
			break;
		case ACTION_ADD:
			fprintf(stderr, "Adding to %s\n", argv[1]);
			par = read_par_header(unist(argv[1]), 1, 0, 0);
			if (!par) return 2;
			cmd.action = ACTION_ADDING;
			break;
		case ACTION_ADDING:
			par_add_file(par, find_file_name(unist(argv[1]), 1));
			break;
		case ACTION_MIX:
			fprintf(stderr, "Unknown argument: '%s'\n", argv[1]);
			break;
		case ACTION_TEXT_UI:
			par_load(unist(argv[1]));
			break;
		}
	}
}
