<?php

/**
* This file functions as a daemon process used to bootstrap and execute the
* client by loading its configuration file, instantiating it and event
* handlers for it, configuring it, and executing its event handling loop.
*/

/**
* If this file is being included rather than executed, just terminate
*/
if ($_SERVER['SCRIPT_NAME'] == __FILE__) {
    return;
}

/**
* Code base version
*
* @const string
*/
define('PHERGIE_VERSION', '1.0.2');

/**
* Path to the configuration file used by default when one is not specified or
* register_argc_argv is disabled in php.ini
*
* @const string
*/
define('PHERGIE_INI', 'phergie.ini');

/**
* Path to the directory containing the Phergie directory
*
* @const string
*/
define('PHERGIE_DIR', dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR);

/**
* Add the Phergie directory to the include path
*/
set_include_path(
    get_include_path()
    . PATH_SEPARATOR .
    PHERGIE_DIR
);

/**
* Check to make sure the CLI SAPI is being used
*/
if (php_sapi_name() != 'cli') {
    trigger_error('Phergie is intended to be run using the CLI SAPI for PHP', E_USER_ERROR);
}

/**
* Allow the bot to run indefinitely
*/
set_time_limit(0);

/**
* Determine what configuration file should be used
*/
if (!ini_get('register_argc_argv')) {
    echo 'The register_argc_argv setting in php.ini is disabled, defaulting to ' . PHERGIE_INI . "\n";
    $ini = PHERGIE_INI;
} else if ($argc == 1) {
    echo 'No configuration file specified, defaulting to ' . PHERGIE_INI . "\n";
    $ini = PHERGIE_INI;
} else {
    $ini = $argv[1];
}

/**
* Obtain and validate the contents of the configuration file
*/
$required = array('server', 'username', 'nick');
$config = @parse_ini_file(PHERGIE_DIR . 'Phergie' . DIRECTORY_SEPARATOR . $ini);

if (count($config) == 0) {
    echo 'Configuration file inaccessible or empty: ' . $ini . "\n";
    return;
}

foreach ($required as $setting) {
    if (!isset($config[$setting]) || empty($config[$setting])) {
        echo 'Required configuration setting missing: ' . $setting . "\n";
        return;
    }
}

/**
* Configure the client
*/
if (isset($config['driver'])) {
    $driver = ucfirst(strtolower($config['driver']));
} else {
    $driver = 'Streams';
}
require_once 'Phergie/Driver/' . $driver . '.php';
$class = 'Phergie_Driver_' . $driver;
$client = new $class();

foreach ($config as $setting => $value) {
    $client->setIni($setting, $value);
}

/**
* Determine which plugins should be loaded
*/
$all = true;
$include = array();
if (isset($config['plugins'])
    && preg_match('/(all|none)(?: except (.+))?/ADi', $config['plugins'], $match)) {
    $all = $match[1] != 'none';
    if (isset($match[2])) {
        $include = array_map('strtolower', preg_split('/[, ]+/', $match[2]));
    }
}

/**
* Remove temporary global configuration variables from memory
*/
unset($required, $config, $setting, $driver, $class);

/**
* Set up plugins
*/
$iterator = new DirectoryIterator(PHERGIE_DIR . '/Phergie/Plugin');
foreach ($iterator as $entry) {
    if ($iterator->isFile()
        && substr($entry, -4) == '.php'
        && ($all xor in_array(strtolower(substr($entry, 0, -4)), $include))) {
        require_once 'Phergie/Plugin/' . $entry;
        $class = 'Phergie_Plugin_' . str_replace('.php', '', $entry);
        $instance = new $class($client);
        $client->addPlugin($instance);
        $client->debug('Loaded ' . $instance->getName());
    }
}

/**
* Remove temporary plugin configuration variables from memory
*/
unset($iterator, $class, $entry, $all, $exclude, $reflector);

/**
* Execute the event handling loop for the client
*/
$client->run();