<?php

function register_component($opts = null) {

    global $components;

    if (!is_array($opts))
        return false;

    // grab the name, remove from opts, then check for sanity
    $name = grab_array_var($opts, COMPONENT_NAME);
    if ($name !== null)
        unset($opts[COMPONENT_NAME]);

    if (empty($name))
        return false;

    if (!isset($components))
        $components = array();

    // get the component server_type (default to fusion type if not specified)
    $server_type = grab_array_var($opts, COMPONENT_SERVER_TYPE, SERVER_TYPE_FUSION);
    $opts[COMPONENT_SERVER_TYPE] = $server_type;

    // we register the component even if the version doesn't match
    // so that it shows up with an error message and can allow user action
    $components[$name] = $opts;

    // check for required version flag
    $req_version = intval(grab_array_var($opts, COMPONENT_REQUIRES_VERSION, 0));
    if ($req_version > get_product_release()) {

        $error_message = grab_array_var($opts, COMPONENT_ERROR_MESSAGE, 
            sprintf(_('This component requires Nagios Fusion release %s or greater and is not currently active!'), $req_version));

        // make sure we know it isn't registered and set the error message (to display in manage components)
        $components[$name][COMPONENT_REGISTERED] = false;
        $components[$name][COMPONENT_ERROR_MESSAGE] = $error_message;

        // we don't use a config function if we failed req version
        unset($components[$name][COMPONENT_CONFIG_FUNCTION]);

        log_error(LOG_TYPE_SYSTEM, "tried registering component '$name', but the required version '$req_version' is higher than Fusion");
        return false;
    }

    // is there a function we should execute after succesful component registration?
    $reg_function = grab_array_var($opts, COMPONENT_FUNCTION);
    if ($reg_function !== null && function_exists($reg_function))
        $reg_function();

    $components[$name][COMPONENT_REGISTERED] = true;
    return true;
}


/**
 * @param string $name
 * @param bool   $fullpath
 *
 * @return string
 */
function get_component_url_base($name = "", $fullpath = true)
{
    $url = get_base_url($fullpath) . "includes/components/" . $name;
    return $url;
}

/**
 * @param string $name
 *
 * @return string
 */
function get_component_dir_base($name = '')
{
    $url = get_base_dir() . "/includes/components/{$name}";
    return $url;
}


// tests if component is installed
/**
 * @param $name
 *
 * @return bool
 */
function is_component_installed($name)
{
    global $components;

    if (array_key_exists($name, $components))
        return true;

    return false;
}


/**
 * @param null $args
 *
 * @return int
 */
function install_component($args = null)
{
    if ($args == null)
        return 0;
    if (!is_array($args))
        return 0;

    $component_name = grab_array_var($args, "component_name");
    $component_dir = grab_array_var($args, "component_dir");

    log_debug(LOG_TYPE_SYSTEM, "install_component(): Installing component: {$component_name}");

    log_debug(LOG_TYPE_SYSTEM, "install_component(): Checking for install script: {$install_script}");
    if (@file_exists($install_script)) {

        log_debug(LOG_TYPE_SYSTEM, "install_component(): Install script found. Running...");

        // make the script executable
        chmod($install_script, 0755);

        // run the script
        system($install_script, $retval);

        log_debug(LOG_TYPE_SYSTEM, "install_component(): Install script finished. Result: {$retval}");
        return $retval;
    }

    return 0;
}


function get_all_components_needing_upgrade()
{
    global $components;
    global $components_api_versions;
    $needs_upgrade = array();

    $tmp = get_tmp_dir() . "/";
    $xmlcache = $tmp . 'components_api_versions.xml';
    if (file_exists($xmlcache)) {
        $components_api_versions = simplexml_load_file($xmlcache);
    }

    $p = dirname(__FILE__) . "/components/";
    $subdirs = scandir($p);

    foreach ($subdirs as $g) {

        if ($g == '.' || $g == '..' || $g == '.svn' || $g == 'componenthelper.inc.php' || $g == "xicore") {
            continue;
        }

        $d = $p . $g;

        if (is_dir($d)) {
            $f = $d . "/$g.inc.php";
            if (file_exists($f)) {
                include_once($f);
            }
        }
    }

    //print count($components);

    foreach ($components as $k => $c) {
        if (!empty($c['args']['type'])) { if ($c['args']['type'] == 'core') continue; }
        print $k;
        if (version_compare($c['args']['version'], $components_api_versions->$k->version, '<')) {
            $needs_upgrade[$k] = $c;
        }
    }

    //print_r($needs_upgrade);

    return $needs_upgrade;
}


// TODO: get rid of all @ suppression
function init_components() {

    if (defined('SKIPCOMPONENTS') && constant('SKIPCOMPONENTS') == true)
        return false;

    global $components;

    $parent_dir = dirname(__FILE__) . '/../components/';
    $components_dirs = scandir($parent_dir);
    foreach ($components_dirs as $component_dir) {

        if ($component_dir == '.' || $component_dir == '..')
            continue;

        $this_dir = $parent_dir . $component_dir;
        if (is_dir($this_dir)) {

            $inc_file = $this_dir . "/{$component_dir}.inc.php";
            if (file_exists($inc_file)) {

                // store components in temp var, and reset it
                $components_temp = $components;
                $components = array();

                include_once($inc_file);

                // there should only be one, the current registered component ^ from that include file
                // so set its component directory
                $component_name = null;
                foreach ($components as $name => $component) {

                    // set disabled for non req versions
                    /*
                    if (!empty($component[COMPONENT_REQUIRES_VERSION]) && $component[COMPONENT_REQUIRES_VERSION] > get_product_release())
                        $component[COMPONENT_DISABLED] = true;
                    */

                    $components[$name][COMPONENT_DIRECTORY] = basename($this_dir);
                    $component_name = $name;
                }

                // add that component to the temp var, and then copy the temp var back to components
                if ($component_name !== null)
                    $components_temp[$component_name] = $components[$component_name];

                $components = $components_temp;
            }
        }
    }

    ksort($components, SORT_STRING);
}
