/*
 * Sentinella
 * http://sentinella.sourceforge.net/
 * Copyright (c) 2009-2013 Carlos Olmedo Escobar <carlos.olmedo.e@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <iostream>
#include <stdlib.h>
#include <QtGlobal>
#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#include "MainWindow.h"

int main(int argc, char **argv) {
	KAboutData aboutData("sentinella", NULL, ki18n("Sentinella"), "0.9.2", ki18n(
			"Action launcher based on system activity"), KAboutData::License_GPL_V2, ki18n(
			"Copyright (c) 2009-2013 Carlos Olmedo Escobar"), ki18n(""),
			"http://sentinella.sourceforge.net/",
			"https://sourceforge.net/p/sentinella/bugs/new/");
	aboutData.addAuthor(ki18n("Carlos Olmedo Escobar"), ki18n("Project leader."),
			"carlos.olmedo.e@gmail.com");
	aboutData.addCredit(ki18n("Damon John Hoxworth"), ki18n("Web designer"),
			"damon@solutionarts.net", "http://solutionarts.net/");
	aboutData.addCredit(ki18n("Niels Thykier"), ki18n("Review of the entire package."),
			"niels@thykier.net");
	aboutData.setOtherText(
			ki18n(
					"Icons and audio files released under license: http://creativecommons.org/licenses/by-sa/3.0/ Copyright (c) 2009, 2010 Carlos Olmedo Escobar"));
	KCmdLineArgs::init(argc, argv, &aboutData);

	KCmdLineOptions options;
	options.add("s").add("start", ki18n("The condition will be run immediately."));

	options.add(":", ki18n("Condition options:"));
	options.add("cpu <percentage>", ki18nc("@info Keep '--during', '--lower' and '--higher' in english",
			"CPU load measurement. Use in combination with --during, --lower or --higher."));
	options.add("memory <megabytes>", ki18n(
			"Memory usage in megabytes. Use in combination with --during, --lower or --higher."));
	options.add(
			"network <kb>",
			ki18n(
					"Network traffic in kilobytes/second. Use in combination with --interface, --during and --lower or --higher."));
	options.add("date-time <value>", ki18n(
			"Current date and time condition. The format should be: YYYY-MM-DDTHH:MM:SS"));
	options.add("program-dies <pid>", ki18n(
			"The condition will be met when the process of id <pid> dies."));
	options.add("h").add("higher", ki18n(
			"The condition will be met if the system's activity is higher than your chosen value."));
	options.add("l").add("lower", ki18n(
			"The condition will be met if the system's activity is lower than your chosen value."));
	options.add("d").add("during <time>", ki18n(
			"The time during the condition must be met to throw the action. Format: MM:SS."));
	options.add("i").add(
			"interface <name>",
			ki18n(
					"Sets the name of the network interface to monitor when using the --network parameter."));

	options.add(":", ki18n("Action options:"));
	options.add("shutdown <force>", ki18nc("@info Keep the 'yes' and 'no' in english",
			"Shutdown the computer when the condition is met. <force> values are 'yes' or 'no'."));
	options.add(
			"reboot <force>",
			ki18nc("@info Keep the 'yes' and 'no' in english",
					"Reboot the computer when the condition is met. Possible values for <force> are 'yes' or 'no'."));
	options.add(
			"sleep <mode>",
			ki18nc(
					"@info Keep the 'Standby', 'Suspend' and 'Hibernate' in english",
					"Place computer in sleep mode when the condition is met. Possible values for <mode> are 'Standby', 'Suspend' or 'Hibernate'."));
	options.add("execute-command", ki18n("The command will be read from stdin."));
	options.add("play-alarm", ki18n("Play an alarm as an action."));
	options.add("terminate-program <pid>", ki18n(
			"It will try to terminate the program specified by <pid>."));
	KCmdLineArgs::addCmdLineOptions(options);

	KCmdLineArgs* parsedArgs = KCmdLineArgs::parsedArgs(); // Validating condition parameters
	QByteArray args[] = { "cpu", "memory", "network", "date-time", "program-dies", "" }; // the actions need 6 args
	int i;
	ConditionId cmdChosenCondition = NO_CONDITION;
	for (i = 0; i < 5; ++i) {
		if (parsedArgs->isSet(args[i])) {
			if (cmdChosenCondition == NO_CONDITION)
				cmdChosenCondition = (ConditionId) i;
			else {
				std::cout << qPrintable(
						ki18n("Sorry. You can choose only one condition.").toString()) << std::endl;
				return EXIT_FAILURE;
			}
		}
	}
	if ((cmdChosenCondition == NO_CONDITION || cmdChosenCondition > NETWORK) && (parsedArgs->isSet(
			"higher") || parsedArgs->isSet("lower") || parsedArgs->isSet("during"))) {
		std::cout
				<< qPrintable(
						ki18n(
								"Sorry. Parameters --higher, --lower and --during are only valid in conjunction with --cpu, --memory and --network conditions.").toString())
				<< std::endl;
		return EXIT_FAILURE;
	}

	args[0] = "shutdown"; // Validating action parameters
	args[1] = "reboot";
	args[2] = "sleep";
	args[3] = "execute-command";
	args[4] = "play-alarm";
	args[5] = "terminate-program";
	ActionId cmdChosenAction = NO_ACTION;
	for (i = 0; i < 6; ++i) {
		if (parsedArgs->isSet(args[i])) {
			if (cmdChosenAction == NO_ACTION)
				cmdChosenAction = (ActionId) i;
			else {
				std::cout << qPrintable(ki18n("Sorry. You can choose only one action.").toString())
						<< std::endl;
				return EXIT_FAILURE;
			}
		}
	}

	KApplication app;
	MainWindow mainWindow(
			cmdChosenCondition != NO_CONDITION || cmdChosenAction != NO_ACTION ? parsedArgs : NULL,
			cmdChosenCondition, cmdChosenAction);
	if (app.isSessionRestored()) {
		mainWindow.restore(1, false); // I avoid to use kRestoreMainWindows() because it always shows (through restore()) the window
	} else {
		mainWindow.setObjectName("MainWindow#");
		mainWindow.show();
	}
	return app.exec();
}
