/* $Id$ */

#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <cstdio>
#include "version.h"
#include "cmds.h"
#include "throw.h"
#include "intl.h"
#include "cli.h"

enum ECommand
{
	CMD_UNKNOWN	= 0,
	CMD_CHECK	= 1,
	CMD_GET		= 2,
	CMD_PUT		= 3,
	CMD_IMPORT	= 4,
	CMD_EXPORT	= 5,
	CMD_FSK		= 6,
};

static ECommand CmdFromCLI(const std::string &cmd)
{
	if (cmd == "check")
		return CMD_CHECK;

	if (cmd == "get")
		return CMD_GET;

	if (cmd == "put")
		return CMD_PUT;

	if (cmd == "import")
		return CMD_IMPORT;

	if (cmd == "export")
		return CMD_EXPORT;

	if (cmd == "fsk")
		return CMD_FSK;

	return CMD_UNKNOWN;
}

static ECommand CmdFromProgname(const std::string av0)
{
	// don't use program_invocation_short_name because of portability

	size_t pos(av0.rfind('/'));
	const std::string name((pos == av0.npos) ? av0 : av0.substr(pos + 1));

	if (name.substr(0, 4) != "owx-")
		return CMD_UNKNOWN;

	return CmdFromCLI(name.substr(4));
}

static void Main(int ac, char * const av[])
{
	CCli cli(ac, av, ":c:fhi:m:o:p:r:t:v");

	if (cli.Avail('v'))
	{
		printf(_("Open Wouxun version %s, build %s\n"), VERSION, BUILD);
		printf(_("For details please see: http://owx.chmurka.net/\n"));
		return;
	}

	if (cli.Avail('h'))
	{
		static const char fasthelp[] = _(
			"Options for all programs: -h, -v, -c <command>, -m <model>\n"
			"Options for owx-check, owx-get and owx-put: -f, -p <port>, -t <timeout>\n"
			"Options for owx-check: none\n"
			"Options for owx-get: -o <path>\n"
			"Options for owx-put: -i <path>, -r <path>\n"
			"Options for owx-export: -i <bin path>, -o <csv path>\n"
			"Options for owx-import: -i <csv path>, -o <bin path>\n"
			"Options for owx-fsk: none (ignored)\n"
		);

		printf("%s", fasthelp);
		return;
	}

	ECommand cmd(cli.Avail('c') ? CmdFromCLI(cli.Param('c')) : CmdFromProgname(av[0]));

	void (*fns[])(const CCli &cli) = { CmdUnknown, CmdCheck, CmdGet, CmdPut, CmdImport, CmdExport, CmdFsk };
	fns[cmd](cli);
}

int main(int ac, char * const av[])
{
	try
	{
		Main(ac, av);
	}
	catch (const std::logic_error &e)
	{
		fprintf(stderr, "owx: %s\n", e.what());
		return EXIT_FAILURE;
	};

	return EXIT_SUCCESS;
}
