{{{
<?php
// Allowed arguments & their defaults
$runmode = array(
	'no-daemon' => false,
	'help' => false,
	'write-initd' => false,
	// production environment by default
	'env' => 'production'
);

// Scan command line attributes for allowed arguments
foreach ($argv as $k=>$arg) {
	if (substr($arg, 0, 2) == '--' && isset($runmode[substr($arg, 2)])) {
		$runmode[substr($arg, 2)] = true;
	}
}

// Help mode. Shows allowed argumentents and quit directly
if ($runmode['help'] == true) {
	echo 'Usage: '.$argv[0].' [runmode]' . "\n";
	echo 'Available runmodes:' . "\n";
	foreach ($runmode as $runmod=>$val) {
		echo ' --'.$runmod . "\n";
	}
	die();
}

// Include the class
error_reporting(E_ALL);
require_once "System/Daemon.php";

// 1000 exists locally, but likely won't on a server. What's a good save id to use?
// Hopefully the functions will return the proper ids (owner of this file).
$uid = getmyuid();
$uid = ($uid === false) ? $uid = 1000:$uid;
$gid = getmygid();
$gid = ($gid === false) ? $gid = 1000:$gid;

// Setup
$options = array(
	'appName' => 'li3botd',
	'appDir' => dirname(__FILE__),
	'appDescription' => 'li3 IRC Bot.',
	'authorName' => 'Tom Maiaroto',
	'authorEmail' => 'tom@union-of-rad.com',
	'sysMaxExecutionTime' => '0',
	'sysMaxInputTime' => '0',
	// I think this is JUST the daemon. The command we're calling is via shell_exec() should be it's own thing. So this can be low.
	// If this daemon gets greedy, it'll turn off at 8M of RAM usage. It can be restarted, but let's see how 8M goes.
	'sysMemoryLimit' => '8M',
	'appRunAsGID' => $gid,
	'appRunAsUID' => $uid
);

// Rename the process based on evnironment. Except for production.
if($runmode['env'] != 'production') {
	$options['appName'] = $options['appName'] . '-' . $runmode['env'];
}

System_Daemon::setOptions($options);

// This program can also be run in the forground with runmode --no-daemon
if (!$runmode['no-daemon']) {
	// Spawn Daemon
	System_Daemon::start();
}

// With the runmode --write-initd, this program can automatically write a
// system startup file called: 'init.d'
// This will make sure your daemon will be started on reboot
if (!$runmode['write-initd']) {
	System_Daemon::info('not writing an init.d script this time');
} else {
	if (($initd_location = System_Daemon::writeAutoRun()) === false) {
		System_Daemon::notice('unable to write init.d script');
	} else {
		System_Daemon::info(
			'sucessfully written startup script: %s',
			$initd_location
		);
	}
}

// Run your code
// Here comes your own actual code
// This variable gives your own code the ability to breakdown the daemon:
$runningOkay = true;

// While checks on 3 things in this case:
// - That the Daemon Class hasn't reported it's dying
// - That your own code has been running Okay
// - That we're not executing more than 3 runs
// while (!System_Daemon::isDying() && $runningOkay && $cnt <=3) {
while (!System_Daemon::isDying() && $runningOkay) {
	// What mode are we in?
	$mode = '"'.(System_Daemon::isInBackground() ? '' : 'non-' ).'daemon" mode';

	// Log something using the Daemon class's logging facility
	// Depending on runmode it will either end up:
	//  - In the /var/log/logparser.log
	//  - On screen (in case we're not a daemon yet)
	System_Daemon::info('{appName} running in %s',
		$mode
	);

	// In the actual logparser program, You could replace 'true'
	// With e.g. a  parseLog('vsftpd') function, and have it return
	// either true on success, or false on failure.
	
	$li3_app_path = dirname(dirname(__DIR__));
	// shell_exec() returns null if an error occurred. So if !is_null() should return true.
	$runningOkay = (!is_null(shell_exec("(cd {$li3_app_path} && exec libraries/lithium/console/li3 --env={$runmode['env']} Bot)")));
	
	// Should that return false, then the daemon is automatically shut down.
	// An extra log entry would be nice, we're using level 3, which is critical.
	// Level 4 would be fatal and shuts down the daemon immediately, which in this 
	// case is handled by the while condition.
	if (!$runningOkay) {
		System_Daemon::err('There was an error with the bot, so this will be my last run');
	}

	// Relax the system by sleeping for a little bit iterate also clears statcache
	// System_Daemon::info('{appName} sleeping for %s seconds.', 3);
	
	// This doesn't seem to work properly with exact timing. it may be because it's calling usleep() somehow? I don't know.
	// It'll work for us here because the time we don't care about, but if we wanted to say 3hrs it wouldn't be 3 hrs.
	// See more here: http://pear.php.net/package/System_Daemon/docs/latest/__filesource/fsource_System_Daemon__System_Daemon-1.0.0RC1SystemDaemon.php.html#a595
	System_Daemon::iterate(3);
	
	// Here's all it's suppose to do.
	//sleep(3); // <--- this would be more accurate with time in seconds
	//clearstatcache();
	// ...and for us, using PHP 5.3+
	//gc_collect_cycles();
}

// Shut down the daemon nicely
// This is ignored if the class is actually running in the foreground
System_Daemon::stop();
}}}