<?php
require_once(dirname(__FILE__) . '/../includes/base.inc.php');
block_non_admins();

route_request();
function route_request() {

    $pageopt = get_pageopt();

    switch ($pageopt) {

        case 'delete':
            delete_component();
            break;

        case 'upload':
            upload_component();
            break;

        case 'download':
            download_component();
            break;

        case 'checkupdates':
            check_components();
            break;

        //case 'installupdates':

        case 'config':
            show_config();
            break;

        case 'updateconfig':
            update_config();
            break;

        default:
            show_components();
            break;
    }
}


// Checks with API for component updates via XML
function check_components() {

    // error in demo
    demo_error('show_components');

    $tmp = get_tmp_dir() . '/';
    $xmlcache = $tmp . 'components_api_versions.xml';
    $url = XML_COMPONENT_VERSIONS;

    $proxy = (bool) get_option('use_proxy', 0);

    $options = array(
        'return_info' => true,
        'method' => 'get',
        'timeout' => 10
    );

    // Fetch the url
    $result = load_url($url, $options, $proxy);
    $getfile = trim($result['body']);

    // Make sure we succeeded and the file is an appropriate length
    if ($getfile && strlen($getfile) > 800) {
        file_put_contents($xmlcache, $getfile);
        flash_message(_('Component Versions Updated'));
    } else {
        flash_message(_('Could not download component version list from Nagios Server, check Internet Connnectivity'), 'error');
    }

    show_components();
}

function show_components($reload = false) {

    global $components;
    global $update_components;

    if ($reload)
        reload_page('/admin/', 'components.php');

    $title = _('Manage Components');
    child_page($title);
    echo well_top_page_header($title);
    
    echo '<p>' . _("Manage the components that are installed on this system. Need a custom component created to extend Nagios Fusion's capabilities?") . 
        ' <a href="http://www.nagios.com/contact/" target="_blank">' . _('Contact us') . '</a> ' . _('for pricing information.') . '<br />' .
        _('You can find more components') . ' <a href="http://exchange.nagios.org/directory/Addons/Components/" target="_blank">' . _('on the Exchange') . '</a>.</p>';


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

    $update_components = array();
    foreach ($components as $name => $component) {

        if (!empty($component[COMPONENT_TYPE]) && $component[COMPONENT_TYPE] == COMPONENT_TYPE_CORE)
            continue;

        if (isset($components_api_versions->$name)) {
            if (version_compare($component[COMPONENT_VERSION],  $components_api_versions->$name->version, '<'))
                $update_components[$name] = array(
                        'version' => $components_api_versions->$name->version,
                        'download' => $components_api_versions->$name->download,
                    );
        }
    }


    ?>

    <div class="well" style="margin-top: 10px;">
        <form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin: 0;">

            <input type="hidden" name="upload" value="1">
            <input type="hidden" name="MAX_FILE_SIZE" value="1000000">

            <div class="fl" style="height: 29px; line-height: 29px; margin-right: 10px; font-weight: bold; color: #666;"><?php echo _('Upload a Component'); ?></div>
            <div class="fl" style="margin-right: 10px;">
                <div class="input-group" style="width: 240px;">
                    <span class="input-group-btn">
                        <span class="btn btn-sm btn-default btn-file">
                            <?php echo _('Browse'); ?>&hellip; <input type="file" name="uploadedfile">
                        </span>
                    </span>
                    <input type="text" class="form-control" style="width: 200px;" readonly>
                </div>
            </div>
            <div class="fl">
                <button type="submit" class="btn btn-sm btn-primary"><?php echo _('Upload &amp; Install'); ?></button>
            </div>

            <div class="fr">
                <a href="?checkupdates=true" class="btn btn-sm btn-primary" style="margin-right: 5px;">
                    <i class="fa fa-check l"></i> <?php echo _("Check for Updates"); ?>
                </a>

                <?php
                /*
                <button type="button" class="btn btn-sm btn-success" id="install" style="margin-right: 5px;" <?php if (count($update_components) == 0) { echo 'disabled'; } ?>>
                    <?php echo _("Install Updates"); ?>
                </button>
                */
                ?>
                
                <a href="https://exchange.nagios.org/directory/Addons/Components" class="btn btn-sm btn-default" target="_blank"><?php echo _('More Components'); ?> <i class="fa fa-external-link r"></i></a>
            </div>

            <div class="clear"></div>
        </form>
    </div>

    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th><?php echo _('Component'); ?></th>
                <th class="center" style="width: 54px"><?php echo _('Type'); ?></th>
                <th class="center" style="width: 60px;"><?php echo _('Settings'); ?></th>
                <th class="center" style="width: 70px;"><?php echo _('Actions'); ?></th>
                <th class="center" style="width: 60px;"><?php echo _('Version'); ?></th>
                <th class="center" style="width: 120px;"><?php echo _('Status'); ?></th>
            </tr>
        </thead>
        <tbody>
        <?php
        foreach ($components as $name => $component) {

            // skip core components for this list
            if (!empty($component[COMPONENT_TYPE]) && $component[COMPONENT_TYPE] == COMPONENT_TYPE_CORE)
                continue;

            // component may have just been deleted!
            if (!file_exists(DIRNAME(__FILE__) . '/../includes/components/' . $component[COMPONENT_DIRECTORY]))
                continue;

            show_component($name, $component);
        }
        ?>
        </tbody>
    </table>

    <div id="updates" class="xi-modal hide" style="max-width: 400px;">
        <p><strong><?php echo _('Please verify the changes below.'); ?></strong> <?php echo _('Installing all updates will update the following components'); ?>:</p>
        <ul>
            <?php //foreach ($update_components as $c) { ?>
            <li><?php //echo $c['args'][COMPONENT_TITLE]; ?></li>
            <?php //} ?>
        </ul>
        <div style="padding-top: 20px;">
            <button type="button" class="btn btn-sm btn-success btn-install" style="margin-right: 5px;"><?php echo _('Install'); ?></button>
            <button type="button" class="btn btn-sm btn-default btn-cancel"><?php echo _('Cancel'); ?></button>
        </div>
    </div>

    <h2><?php echo _("Core Components"); ?></h2>
    <p><?php echo _('These are components that are required for Fusion to function normally. These components should not be removed or edited.'); ?></p>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th><?php echo _("Component"); ?></th>
                <?php /* TODO: we should show the server_type here */ ?>
                <th class="center" style="width: 54px"><?php echo _("Type"); ?></th>
                <th class="center" style="width: 60px;"><?php echo _("Settings"); ?></th>
                <th class="center" style="width: 60px;"><?php echo _("Version"); ?></th>
            </tr>
        </thead>
        <tbody>
        <?php
        foreach ($components as $name => $component) {
            
            // skip non core components for this list
            if (empty($component[COMPONENT_TYPE]) || $component[COMPONENT_TYPE] != COMPONENT_TYPE_CORE)
                continue;

            show_component($name, $component);
        }
        ?>
        </tbody>
    </table>

    <?php
    exit();
}

// TODO: consistency. switch the ' & " around down here. this was copied from xi
function show_component($name, $component) {
    
    global $update_components;

    // grab variables
    $type           = grab_array_var($component, COMPONENT_TYPE, "");
    $title          = grab_array_var($component, COMPONENT_TITLE, "");
    $desc           = grab_array_var($component, COMPONENT_DESCRIPTION, "");
    $version        = grab_array_var($component, COMPONENT_VERSION, "");
    $date           = grab_array_var($component, COMPONENT_DATE, "");
    $author         = grab_array_var($component, COMPONENT_AUTHOR, "");
    $homepage       = grab_array_var($component, COMPONENT_HOMEPAGE, "");
    $component_dir  = grab_array_var($component, COMPONENT_DIRECTORY, "");

    $configfunc     = grab_array_var($component, COMPONENT_CONFIG_FUNCTION, "");
    $encrypted      = grab_array_var($component, COMPONENT_ENCRYPTED, false);

    $registered     = grab_array_var($component, COMPONENT_REGISTERED, true);
    $error_message  = grab_array_var($component, COMPONENT_ERROR_MESSAGE);

    echo "<tr>";

    $displaytitle = $name;
    if (!empty($title))
        $displaytitle = $title;

    // Gettext displaytitle and desc because they aren't getting gettexted beforehand
    // somehow the init_language is not getting called before the components are loading in

    $enc_display = '';
    if ($encrypted) {
        $enc_display = ' <i class="fa fa-enc fa-lock tt-bind" title="'._('Encrypted component').'"></i>';
    }

    echo "<td>";
    echo '<div style="font-size: 12px;"><b>' . encode_html($displaytitle) . "</b>" . $enc_display . "</div>";

    if (!$registered)
        echo '<div class="alert alert-danger" style="margin: 5px; font-size: 14px; font-weight: bold;">' . $error_message . '</div>';

    if (!empty($desc))
        echo '<div style="margin: 3px 0 5px 0;">' . encode_html($desc) . '</div>';

    if (!empty($version))
        echo '<i style="color: #555;" class="fa fa-tag tt-bind" title="'._("Version").'"></i> ' . encode_html($version) .'  &nbsp; ';

    if (!empty($date))
        echo '<i style="color: #555;" class="fa fa-calendar tt-bind" title="'._("Release date").'"></i> ' . encode_html($date) . ' &nbsp; ';

    if (!empty($author))
        echo '<i style="color: #555;" class="fa fa-user tt-bind" title="'._("Author").'"></i> ' . encode_html($author) . ' &nbsp; ';

    if (!empty($homepage))
        echo '<i style="color: #555;" class="fa fa-user tt-bind" title="'._("Website").'"'.' <a href="' . encode_html($homepage) . '" target="_blank" rel="noreferrer">' . encode_html($homepage) . '<a/>';

    echo "</td>";

    echo "<td class='center'>";
    switch ($type) {
        case "core":
            echo _("Core");
            break;
        default:
            echo _("User");
            break;
    }
    echo "</td>";

    echo "<td class='center'>";
    if (!empty($configfunc)) {
        echo "<a href='?config=" . $name . "'><img src='" . get_icon_url("editsettings.png") . "' alt=" . _('Edit Settings') . "' title='" . _('Edit Settings') . "' class='tt-bind'></a>";
    } else
        echo "-";
    echo "</td>";

    if ($type != 'core') {
        echo "<td class='center'>";
        echo "<a href='?download=" . $name . "'><img src='" . get_icon_url("package_go.png") . "' alt='" . _('Download') . "' title='" . _('Download') . "' class='tt-bind'></a> ";
        echo "<a href='?delete=" . $name . "&nsp=" . get_nagios_session_protector_id() . "'><img src='" . get_icon_url("cross.png") . "' alt='" . _('Delete') . "' title='" . _('Delete') . "' class='tt-bind'></a>";
        echo "</td>";
    }

    echo "<td class='center'>";
    if ($version != "")
        echo "$version";
    else
        echo "-";
    echo "</td>";

    if ($type != 'core') {
        if (isset($update_components[$name])) {
            echo '<td style="background-color:#B2FF5F;" class="center">';

            $version = '';
            $download = '';

            if (!empty($update_components[$name]['version']))
                $version = $update_components[$name]['version'];
            if (!empty($update_components[$name]['download']))
                $download = $update_components[$name]['download'];

            if (!empty($version))
                echo $version . ' ' . _('Available') . '<br />';

            if (!empty($download))
                echo '<a href="' . $download . '">' . _('Download') . '</a>';

        } else {
            echo '<td class="center">';
            echo _('Up to date');
        }
        echo '</td>';
    }

    echo "</tr>\n";
}

// grab the config function of the specified component
function show_config() {
    global $apply_succeed;
    global $components;

    $name = grab_request_var('config');

    // in case we're coming from a failed update
    if (empty($name))
        $name = grab_request_var('updateconfig');

    if (empty($name) || empty($components[$name])) {
        flash_message(_('No component with that specified name.'), 'error');
        show_components();
    }
    
    if ($apply_succeed == true) {
        $apply_succeed = false;
        flash_message(_('Component Settings Applied!'), 'info');
    }

    $component = $components[$name];

    $component_title = grab_array_var($component, COMPONENT_TITLE);
    $component_config_function = grab_array_var($component, COMPONENT_CONFIG_FUNCTION);

    if (empty($component_config_function) || !function_exists($component_config_function)) {
        flash_message(_('That component has no configure function.'), 'error');
        show_components();
    }

    $title = _('Component Configuration') . ' &middot; ' . $component_title;

    child_page($title);
    echo well_top_page_header($title);

    ?>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
        <input type="hidden" name="updateconfig" value="<?php echo encode_html($name); ?>">

        <?php

        // get component output
        $output = $component_config_function(COMPONENT_CONFIG_MODE_GET);
        echo $output;

        ?>

        <div id="formButtons">
            <input id="submitButton" type="submit" class="submitbutton btn btn-sm btn-primary" name="submitButton" value="<?php echo _('Apply Settings'); ?>">
            <a href="<?php echo $_SERVER['PHP_SELF']; ?>" class="submitbutton btn btn-sm btn-default"><?php echo _('Cancel'); ?></a>
        </div>

    </form>
    <?php
}

function update_config() {

    // error in demo
    demo_error('show_config');
    global $apply_succeed;
    global $components;

    $name = grab_request_var('updateconfig', '');

    if (empty($name) || empty($components[$name])) {
        flash_message(_('No component with that specified name.'), 'error');
        show_components();
    }

    $component = $components[$name];
    $component_config_function = grab_array_var($component, COMPONENT_CONFIG_FUNCTION);

    if ($component_config_function(COMPONENT_CONFIG_MODE_SET)) {
        $apply_succeed = true;
        show_config();
    }
    else
        show_config();
}

function upload_component() {

    check_nagios_session_protector();

    // error in demo
    demo_error('show_components');

    global $components;

    $target_path = get_tmp_dir() . '/';
    $component_file = preg_replace('/[^A-Za-z0-9\.\-]/', '', basename($_FILES['uploadedfile']['name']));
    $target_path .= "component-{$component_file}";

    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {

        // fix perms
        chmod($target_path, 0770);
        chgrp($target_path, 'nagios');

        $command_id = submit_command(COMMAND_INSTALL_COMPONENT, $component_file);
        if ($command_id === false || $command_id <= 0) {
            flash_message(_('Unable to submit command.'), 'error');
            show_components();
        }

        if ($command = wait_for_command($command_id)) {
            if ($command['result_code'] == COMMAND_RESULT_OK) {
                flash_message(_('Component successfully installed.'));
                header('Location: ' . $_SERVER['PHP_SELF']);
                exit();
            } else {
                if (!empty($command['result'])) {
                    flash_message($command['result'], 'error');
                } else {
                    flash_message(_('Something went wrong installing component.'), 'error');
                }
            }
        } else {
            flash_message(_('Component scheduled for installation.'));
        }
    } else {
        flash_message(_('Unable to move uploaded file. Check your permissions on ') . get_tmp_dir(), 'error');
    }

    show_components();
}

function delete_component() {

    check_nagios_session_protector();

    // error in demo
    demo_error('show_components');

    global $components;

    $name = grab_request_var('delete', '');

    if (empty($name) || empty($components[$name])) {
        flash_message(_('No component with that specified name.'), 'error');
        show_components();
    }

    $command_id = submit_command(COMMAND_DELETE_COMPONENT, $name);
    if ($command_id === false || $command_id <= 0) {
        flash_message(_('Unable to submit command.'), 'error');
        show_components();
    }

    if ($command = wait_for_command($command_id)) {

        if ($command['result_code'] == COMMAND_RESULT_OK) {

            flash_message(_('Component successfully deleted.'));
            header('Location: ' . $_SERVER['PHP_SELF']);
            exit();
            
        } else {
            flash_message(_('Something went wrong deleting component.'), 'error');
        }
    } else {
        flash_message(_('Component scheduled for deletion.'));
    }

    show_components();
}

function download_component() {

    global $components;
    
    // error in demo
    demo_error('show_components');

    $name = grab_request_var('download', '');

    if (empty($name) || empty($components[$name]) || empty($components[$name][COMPONENT_DIRECTORY])) {
        flash_message(_('No component with that specified name.'), 'error');
        show_components();
    }

    $dir = $components[$name][COMPONENT_DIRECTORY];

    $command_id = submit_command(COMMAND_PACKAGE_COMPONENT, $dir);
    if ($command_id === false || $command_id <= 0) {
        flash_message(_('Unable to submit command.'), 'error');
        show_components();
    }

    if ($command = wait_for_command($command_id, $time_to_wait = 10)) {

        if ($command['result_code'] == COMMAND_RESULT_OK) {

            $file = get_tmp_dir() . "/component-{$dir}.zip";

            header('Content-type: ');
            header('Content-length: ' . filesize($file));
            header('Content-Disposition: attachment; filename="' . basename($file) . '"');
            readfile($file);
            exit();

        } else {
            flash_message(_('Something went wrong packaging component.'), 'error');
        }
    } else {
        flash_message(_('Component packaging timed out.'), 'error');
    }

    show_components();
}