#!/usr/bin/php
<?php
/**
 * ```
 *  _                              
 * | |__  _ __ __ ___   _____  ___ 
 * | '_ \| '__/ _` \ \ / / _ \/ __|
 * | |_) | | | (_| |\ V / (_) \__ \
 * |_.__/|_|  \__,_| \_/ \___/|___/
 * ```
 * 
 * Bravos - Log monitor
 *
 * @copyright Noumenia (C) 2025 - All rights reserved - Software Development - www.noumenia.gr
 * @license GNU GPL v3.0
 * @package bravos
 * @subpackage cli
 */

// Cli execution only
if(php_sapi_name() !== "cli") {

	echo "[ERROR] This script can only be executed under a PHP shell cli.\n";
	exit(9);

}

// Parse command line parameters
$cmdParameters = getopt(

	// Short
	"Vhvu:g:p:l:i:",

	// Long
	array(
		"version",
		"help",
		"verbose",
		"user:",
		"group:",
		"pid:",
		"processlimit:",
		"ini:",
		"logfiles:"
	)

);
if($cmdParameters === false)
	$cmdParameters = array();

// Handle invalid parameters
foreach($cmdParameters as $key => &$value) {

	// Log files can be set multiple times
	if($key === "logfiles")
		continue;

	// Convert arrays of multiple parameters of the same name into a single string
	if(is_array($value))
		$value = array_pop($value);

	if(!is_string($value))
		$value = "";

}
/** @var array<string, list<string>|string> $cmdParameters */

// Clean-up
unset($value);

// Composer or RPM packages
if(is_file(__DIR__ . "/vendor/autoload.php")) {

	require_once(__DIR__ . "/vendor/autoload.php");

} else {

	// Autoload libLoggerPHP
	require_once("/usr/share/php/libLoggerPHP/controller/common.inc.php");

	// Autoload libSDManagerPHP
	require_once("/usr/share/php/libSDManagerPHP/controller/common.inc.php");

}

// Load common library objects and default configuration parameters
if(is_file(__DIR__ . "/controller/common.inc.php")) {

	require_once(__DIR__ . "/controller/common.inc.php");

} elseif(is_file("/usr/share/php/bravos/controller/common.inc.php")) {

	require_once("/usr/share/php/bravos/controller/common.inc.php");

} else {

        $error = "[bravos: ERROR - Failed to load the common autoloader: bravos/controller/common.inc.php]";
        syslog(LOG_ERR, $error);
        echo $error . "\n";
        exit(9);

}

// Parse parameters
if(
	isset($cmdParameters['V']) ||
	isset($cmdParameters['version']) ||
	isset($cmdParameters['h']) ||
	isset($cmdParameters['help'])
) {

	if(is_file(__DIR__."/controller/help.inc.php")) {

		include __DIR__."/controller/help.inc.php";

	} elseif(is_file("/usr/share/php/bravos/controller/help.inc.php")) {

		include "/usr/share/php/bravos/controller/help.inc.php";

	} else {

		$error = "[bravos: ERROR - Failed to load the help file: bravos/controller/help.inc.php]";
		syslog(LOG_ERR, $error);
		echo $error . "\n";
		exit(9);

	}

}

// Daemon user
if(isset($cmdParameters['u']))
	Config::write("daemonUser", $cmdParameters['u']);
elseif(isset($cmdParameters['user']))
	Config::write("daemonUser", $cmdParameters['user']);

// Daemon group
if(isset($cmdParameters['g']))
	Config::write("daemonGroup", $cmdParameters['g']);
elseif(isset($cmdParameters['group']))
	Config::write("daemonGroup", $cmdParameters['group']);

// PID file
if(isset($cmdParameters['p']))
	Config::write("filePid", $cmdParameters['p']);
elseif(isset($cmdParameters['pid']))
	Config::write("filePid", $cmdParameters['pid']);

// Process limit
if(isset($cmdParameters['l']))
	Config::write("processLimit", intval($cmdParameters['l']));
elseif(isset($cmdParameters['processlimit']))
	Config::write("processLimit", intval($cmdParameters['processlimit']));

// Log file
if(isset($cmdParameters['logfiles'])) {

	if(!is_array($cmdParameters['logfiles']))
		Config::write("logFiles", array($cmdParameters['logfiles']));
	else
		Config::write("logFiles", $cmdParameters['logfiles']);

}

// Type checks
$daemonUser = Config::readStr("daemonUser");
$daemonGroup = Config::readStr("daemonGroup");
$filePid = Config::readStr("filePid");
$processLimit = Config::read("processLimit");
if(!is_int($processLimit))
	$processLimit = 1024;

// Change current directory to the same location as the file PID
if(!empty($filePid)) {

	// Extract the directory only
	$dirPid = dirname($filePid);

	// Validate that it exists
	if(!is_dir($dirPid)) {

		// Create PID directory
		$rc = @mkdir($dirPid, 0755);
		if($rc === false) {

			\libLoggerPHP\Log::error("[bravos: ERROR - PID directory error, could not create the PID directory]");
			exit(9);

		}

		$rc = chown($dirPid, $daemonUser);
		if($rc === false) {

			\libLoggerPHP\Log::error("[bravos: ERROR - PID directory error, could not set the user owner]");
			exit(9);

		}

		$rc = chgrp($dirPid, $daemonGroup);
		if($rc === false) {

			\libLoggerPHP\Log::error("[bravos: ERROR - PID directory error, could not set the group owner]");
			exit(9);

		}

	}

	// Change to the PID directory
	$rc = chdir($dirPid);
	if($rc === false) {

		\libLoggerPHP\Log::error("[bravos: ERROR - Failed to change to the PID directory: " . $dirPid . "]");
		exit(9);

	}

	// Clean-up
	unset($dirPid);

}

try {

	// Create bravos daemon
	$daemon = new Bravos(
		$daemonUser,
		$daemonGroup,
		$filePid,
		$processLimit
	);

} catch(Exception $e) {

	\libLoggerPHP\Log::error("EXCEPTION " . $e->getMessage());
	exit(9);

}

// Start monitoring
$daemon->start();

