<?php
require_once(dirname(__FILE__) . '/../includes/base.inc.php');
block_non_admins();
block_cloud();
block_demo(_('System Updates'));


define('AU_LOGFILE', get_root_dir() . '/tmp/upgrade.log');
define('AU_LOGDIR', get_root_dir() . '/var/upgrades');


route_request();
function route_request()
{
    global $dashlets;

    $cmd = grab_request_var('cmd');

    if ($cmd == "update") {
        do_update();
    } else if ($cmd == "download") {
        download_update_log(grab_request_var('name'));
    } else if ($cmd == "status") {
        check_update_status();
    } else if ($cmd == "acknowledge") {
        set_option("last_update_acknowledged", 1);
        exit();
    } else if ($cmd == "getupdatelog") {
        get_update_log();
    } else if ($cmd == "deletelog") {
        delete_update_log();
    } else if ($cmd == "refresh") {
        do_update_check(true);
        $fusion_update = empty($dashlets['fusion_update']) ? false : $dashlets['fusion_update'];
        echo get_inline_dashlet_html($fusion_update);
        exit();
    }
    
    set_option("last_update_acknowledged", 1);
    show_updates();
}


function show_updates()
{
    global $dashlets;
    global $db;

    $cmd_id = 0;
    $locked = false;
    $update_available = get_option("update_available", 0);
    $last_update_acknowledged = get_option("last_update_acknowledged", 1);

    $title = _('Check for Updates');
    child_page($title);
    echo well_top_page_header($title);

    $fusion_update = empty($dashlets['fusion_update']) ? false : $dashlets['fusion_update'];
?>

    <script type="text/javascript">
    var COMMAND_ID = <?php echo intval($cmd_id); ?>;
    var WCOMMAND = 0;
    var EXITCOUNT = 0;

    $(document).ready(function() {
        // Testing the update button
        $('#check_for_update').click(function () {
            $('#check_for_update').prop("disabled", true);
            $('.update-spinner').show();
            update_dashlet();
        });

        // Stop use from doing update unless they really need to
        $('#perform_update').click(function() {
            if (confirm("Are you sure you want to upgrade Nagios Fusion?")) {
                return true;
            }
            return false;
        });

        $('#go-back').click(function() {
            $.get('updates.php', { 'cmd': 'acknowledge' }, function() {
                window.location.href = "updates.php";
            });
        });

        // Delete the update history
        $('#update-history .delete').click(function () {
            var a = $(this);
            var conf = confirm("<?php echo _('Are you sure you want to delete this update log file?'); ?>");
            if (conf) {
                $.post("updates.php", { cmd: 'deletelog', name: a.data('name') }, function (data) {
                    if (data.success == 1) {
                        a.parents("tr").hide();
                    }
                }, 'json');
            }
        });

        // View the update history
        $('#update-history .view').click(function () {
            var a = $(this);
            show_throbber();
            $.get("updates.php", { cmd: 'getupdatelog', name: a.data('name') }, function (data) {
                var text_header = "<?php echo _('View Update Log'); ?>";
                var update_ran = "<?php echo _('Update Ran:'); ?>" + " " + data.date;
                var update_status = "<?php echo _('Update Status:'); ?>" + " <Strong>" + data.status + "</strong>";
                var text_desc = update_status + " (" + update_ran + ")";

                var content = "<div id='popup_header'><b>" + text_header + "</b></div><div id='popup_data'><p>" + text_desc + "</p></div>";
                content += "<div><textarea style='width: 600px; height: 240px;' class='code'>" + data.contents + "</textarea></div>";

                hide_throbber();
                $('#child_popup_container').html(content);
                display_child_popup();
            }, 'json');
        });

    });

    function update_dashlet() {
        $.post('updates.php', { 'cmd': 'refresh' }, function(data) {
            $('.update-dashlet').html(data);
            $('#check_for_update').prop("disabled", false);
            $('.update-spinner').hide();
        });
    }

    function au_watch_command() {      
        $.ajax('updates.php', {
            dataType: 'json',
            timeout: 1000,
            data: { 'cmd': 'status', 'cmd_id': COMMAND_ID },
            success: function(data, status) {
                if (data == null || data.status_code == 2) {
                    clearInterval(WCOMMAND);
                    $('#go-back').show();
                    $('.upgrade-spinner').hide();
                    if (data.result_code == 0) {
                        $('.upgrade-alert').removeClass('alert-info').addClass('alert-success');
                        $('.upgrade-alert .text').html('<?php echo _("Upgrade was successful!"); ?>');
                    } else {
                        $('.upgrade-alert').removeClass('alert-info').addClass('alert-error');
                        $('.upgrade-alert .text').html('<?php echo _("Upgrade encountered an error."); ?>');
                    }
                } else if (data.status_code == 1) {
                    if (data.stream != "") {
                        $('.upgrade-alert .text').html('<?php echo _("Upgrade in progress..."); ?>');
                    }
                }
                $('#output').text(data.stream);
                $('#output').scrollTop($('#output')[0].scrollHeight);
            },
            error: function() {
                EXITCOUNT++;
                console.log(EXITCOUNT);
                if (EXITCOUNT >= 30) {
                    clearInterval(WCOMMAND);
                    $('#go-back').show();
                    $('.upgrade-spinner').hide();
                    $('.upgrade-alert').removeClass('alert-info').addClass('alert-error');
                    $('.upgrade-alert .text').html('<?php echo _("Upgrade encountered an error."); ?>');
                }
            }
        });
    }
    </script>

    <div class="upgrade-alert alert alert-info hide">
        <i class="upgrade-spinner fa fa-pulse fa-fw fa-14 fa-spinner"></i> <span class="text"><?php echo _("Please wait. Upgrade is starting..."); ?></span>
    </div>

    <button type="button" id="go-back" <?php if ($locked || $last_update_acknowledged) { echo 'style="display: none;"'; } ?> class="btn btn-sm btn-default"><?php echo _("Go Back"); ?></button>

    <div class="info" <?php if ($locked || !$last_update_acknowledged) { echo 'style="display: none;"'; } ?>>

        <button type="button" class="btn btn-sm btn-primary" id="check_for_update"><?php echo _('Check For Updates Now'); ?></button>
        <span class="update-spinner hide">
            <i class="fa fa-pulse fa-spinner fa-fw fa-14"></i>
            <?php echo _("Checking"); ?>...
        </span>

        <div class="block update-dashlet">
            <?php echo get_inline_dashlet_html($fusion_update); ?>
        </div>

    </div>

<?php
    exit();
}


// ===========================
// UPGRADE LOGS
// ===========================


function au_clean_filename($filename)
{
    $filename = str_replace("..", "", $filename);
    $filename = str_replace("/", "", $filename);
    $filename = str_replace("\\", "", $filename);
    return $filename;
}


// Download a single upgrade log
function download_update_log($name)
{
    if (!empty($name)) {
        $filename = $name . ".log";
        $thefile = AU_LOGDIR . '/' . au_clean_filename($filename);

        header('Content-type: text/plain');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        readfile($thefile);

        exit();
    }
}

// Get an update log to display (AJAX)
function get_update_log()
{
    $name = grab_request_var("name");
    $logs = get_nagiosfusion_upgrade_logs();

    foreach ($logs as $log) {
        if ($log['name'] == $name) {
            $log['contents'] = file_get_contents(AU_LOGDIR . '/' . $log['file']);
            print json_encode($log);
            exit();
        }
    }
}

// Delete a log file (AJAX)
function delete_update_log()
{
    $name = grab_request_var("name", "");

    if (!empty($name)) {
        $filename = $name . ".log";
        unlink(AU_LOGDIR . '/' . au_clean_filename($filename));
    }

    // send update
    print json_encode(array("success" => 1));
    exit();
}


// Get a list of all the logs
function get_nagiosfusion_upgrade_logs()
{
    $log_dir = get_root_dir() . "/var/upgrades";
    $upgrades = array();
    if (is_dir(AU_LOGDIR)) {
        $direntries = file_list(AU_LOGDIR, "/\.log/");
        foreach ($direntries as $de) {
            $logfile = $de;
            $name = str_replace(".log", "", $de);
            $ar = explode(".", $de);
            $ts = filemtime(AU_LOGDIR."/$logfile");
            $upgrades[] = array("file" => $logfile,
                "name" => $name,
                "status" => ucfirst($ar[0]),
                "timestamp" => $ts,
                "date" => user_date($ts));
        }
    }
    return $upgrades;
}


/**
 * Gets a list of files in a directory
 * (http://www.php.net/manual/en/function.scandir.php#90628)
 *
 * @param   string  $d  Directory to list
 * @param   string  $x  Regex to match against
 * @return  array       Array of file in a directory
 */
function file_list($d, $x)
{
    $l = array();
    foreach (array_diff(scandir($d), array('.', '..')) as $f) {
        //echo "EXAMINING: $f\n";
        if (is_file($d . '/' . $f) && (($x) ? preg_match($x, $f) : 1))
            $l[] = $f;
    }
    return $l;
}


// ===========================
// AJAX COMMANDS
// ===========================


function check_update_status()
{
    global $db;
    $cmd_id = grab_request_var('cmd_id');

    $bind_array = array(':command_id' => $cmd_id);
    $command = $db->exec_query('SELECT * FROM commands WHERE command_id = :command_id LIMIT 1', $bind_array);
    
    $logfile = file_get_contents(AU_LOGFILE);

    $obj = $command[0];
    $obj['stream'] = $logfile;
    echo json_encode($obj);

    exit();
}


function do_update()
{
    set_option("last_update_acknowledged", 0);
    $cmd_id = submit_command(COMMAND_UPGRADE_TO_LATEST);
    sleep(1);
    header('Location: updates.php');
    die();
}