///////////////////////////////////////////////////////////////////////////////
//
/// \file       main.c
/// \brief      main()
//
//  Copyright (C) 2007 Lasse Collin
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
///////////////////////////////////////////////////////////////////////////////

#include "private.h"
#include "open_stdxxx.h"
#include <ctype.h>

static sig_atomic_t exit_signal = 0;


static void
signal_handler(int sig)
{
	// FIXME Is this thread-safe together with main()?
	exit_signal = sig;

	user_abort = 1;
	return;
}


static void
establish_signal_handlers(void)
{
	struct sigaction sa;
	sa.sa_handler = &signal_handler;
	sigfillset(&sa.sa_mask);
	sa.sa_flags = 0;

	static const int sigs[] = {
		SIGHUP,
		SIGINT,
		SIGPIPE,
		SIGTERM,
		SIGXCPU,
		SIGXFSZ,
	};

	for (size_t i = 0; i < sizeof(sigs) / sizeof(sigs[0]); ++i) {
		if (sigaction(sigs[i], &sa, NULL)) {
			errmsg(V_ERROR, _("Cannot establish signal handlers"));
			my_exit(ERROR);
		}
	}

	/*
	SIGINFO/SIGUSR1 for status reporting?
	*/
}


static bool
is_tty_stdin(void)
{
	const bool ret = isatty(STDIN_FILENO);
	if (ret) {
		// FIXME: Other threads may print between these lines.
		// Maybe that should be fixed. Not a big issue in practice.
		errmsg(V_ERROR, _("Compressed data not read from "
				"a terminal."));
		errmsg(V_ERROR, _("Use `--force' to force decompression."));
		show_try_help();
	}

	return ret;
}


static bool
is_tty_stdout(void)
{
	const bool ret = isatty(STDOUT_FILENO);
	if (ret) {
		errmsg(V_ERROR, _("Compressed data not written to "
				"a terminal."));
		errmsg(V_ERROR, _("Use `--force' to force decompression."));
		show_try_help();
	}

	return ret;
}


static char *
read_name(void)
{
	size_t size = 256;
	size_t pos = 0;
	char *name = malloc(size);
	if (name == NULL) {
		out_of_memory();
		return NULL;
	}

	while (true) {
		const int c = fgetc(opt_files_file);
		if (c == EOF) {
			free(name);

			if (ferror(opt_files_file))
				errmsg(V_ERROR, _("%s: Error reading "
						"filenames: %s"),
						opt_files_name,
						strerror(errno));
			else if (pos != 0)
				errmsg(V_ERROR, _("%s: Unexpected end of "
						"input when reading "
						"filenames"), opt_files_name);

			return NULL;
		}

		if (c == '\0' || c == opt_files_split)
			break;

		name[pos++] = c;

		if (pos == size) {
			size *= 2;
			char *tmp = realloc(name, size);
			if (tmp == NULL) {
				free(name);
				out_of_memory();
				return NULL;
			}

			name = tmp;
		}
	}

	if (name != NULL)
		name[pos] = '\0';

	return name;
}


int
main(int argc, char **argv)
{
	// Make sure that stdin, stdout, and and stderr are connected to
	// a valid file descriptor. Exit immediatelly with exit code ERROR
	// if we cannot make the file descriptors valid. Maybe we should
	// print an error message, but our stderr could be screwed anyway.
	open_stdxxx(ERROR);

	// Set the program invocation name used in various messages.
	argv0 = argv[0];

	setlocale(LC_ALL, "en_US.UTF-8");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	// Set hardware-dependent default values. These can be overriden
	// on the command line, thus this must be done before parse_args().
	hardware_init();

	char **files = parse_args(argc, argv);

	if (opt_mode == MODE_COMPRESS && opt_stdout && is_tty_stdout())
		return ERROR;

	if (opt_mode == MODE_COMPRESS)
		lzma_init_encoder();
	else
		lzma_init_decoder();

	io_init();
	process_init();

	if (opt_mode == MODE_LIST) {
		errmsg(V_ERROR, "--list is not implemented yet.");
		my_exit(ERROR);
	}

	// Hook the signal handlers. We don't need these before we start
	// the actual action, so this is done after parsing the command
	// line arguments.
	establish_signal_handlers();

	while (*files != NULL && !user_abort) {
		if (strcmp("-", *files) == 0) {
			if (!opt_force) {
				if (opt_mode == MODE_COMPRESS) {
					if (is_tty_stdout()) {
						++files;
						continue;
					}
				} else if (is_tty_stdin()) {
					++files;
					continue;
				}
			}

			if (opt_files_name == stdin_filename) {
				errmsg(V_ERROR, _("Cannot read data from "
						"standard input when "
						"reading filenames "
						"from standard input"));
				++files;
				continue;
			}

			*files = (char *)stdin_filename;
		}

		process_file(*files++);
	}

	if (opt_files_name != NULL) {
		while (true) {
			char *name = read_name();
			if (name == NULL)
				break;

			if (name[0] != '\0')
				process_file(name);

			free(name);
		}

		if (opt_files_name != stdin_filename)
			(void)fclose(opt_files_file);
	}

	io_finish();

	if (exit_signal != 0) {
		struct sigaction sa;
		sa.sa_handler = SIG_DFL;
		sigfillset(&sa.sa_mask);
		sa.sa_flags = 0;
		sigaction(exit_signal, &sa, NULL);
		raise(exit_signal);
	}

	my_exit(exit_status);
}
