<?php
    $check_boxs = [
        ["name" => "used", "caption" => "Занятые", "default" => false, "show_for_proxy" => false],
        ["name" => "unused", "caption" => "Свободные", "default" => false, "show_for_proxy" => false],
        ["name" => "neighbors", "caption" => "Соседи", "default" => true, "show_for_proxy" => true],
        ["name" => "all_neighbors", "caption" => "Все Соседи", "default" => false, "show_for_proxy" => true],
        ["name" => "problem_only", "caption" => "Только проблемные", "default" => false, "show_for_proxy" => true],
        ["name" => "check_conf", "caption" => "Проверять конфиги", "default" => false, "show_for_proxy" => true],
    ];
?>

<script type="text/javascript">
    var saved_description_free = "";
    window.onload = function() {
        disable_links = false;
        koolajax.callback(build_free_cluster_structure(document.getElementById("min_ok_uptime_sec").value), onDoneRebuildFree);
    }

    function onDoneRebuildFree(s) {
        if (s !== saved_description_free) {
            document.getElementById("free_cluster_structure").innerHTML = s;
            saved_description_free = s;
        }
        setTimeout(function() {
            koolajax.callback(build_free_cluster_structure(document.getElementById("min_ok_uptime_sec").value), onDoneRebuildFree);
        }, 1000);
    }

    function join(previousStr, currentItem, i) {
        var element = document.getElementById(currentItem.name + "_cb")
        if (element == null)
            return previousStr;
        else
            return previousStr + "&" + currentItem.name + "=" + (element.checked ? "1" : "0");
    }

    function onFilterCheckboxClick(params) {
        var check_boxs = JSON.parse('<?php echo json_encode($check_boxs);?>');
        var str = check_boxs.reduce(join, params);
        document.location.href = str;
    }
</script>

<?php
$slot_filter_state = array();
foreach ($check_boxs as $cb) {
    if (array_key_exists($cb["name"], $_GET))
        $slot_filter_state[$cb["name"]] = (int)($_GET[$cb["name"]]) != 0;
    else
        $slot_filter_state[$cb["name"]] = $cb["default"];
}

function compare_id($a, $b) {
    return strcmp($a["id"], $b["id"]);
}

function get_limited_color($value, $limit, $ok, $ok_color) {
    if ($limit == 0)
        return "";
    $ratio = (float)$value / $limit;
    if ($ratio < $ok)
        return "";
    $int_ratio = (int)(0xff * min(1., ($ratio - $ok) / (1 - $ok)));
    $clr = $ok_color - $int_ratio * ($ok_color - 0xff0000) / 0xff;
    return " style='background-color:#" . sprintf("%06X",$clr) . "'";
}

function get_service_href_html($slot, $service_name) {
    $ctype = $slot["result.config.DaemonConfig.0.Controller.0.DMOptions.0.CType"];
    $service_type = $slot["result.config.DaemonConfig.0.Controller.0.DMOptions.0.ServiceType"];
    if ($ctype == "" || $service_type == "") {
        return $service_name;
    }
    return "<a href=\"" . get_service_url($service_name, $ctype, $service_type, "service_cluster_info") ."\">$service_name</a>";
}

function build_free_cluster_structure($minOkUptime) {
    global $ctype_cgi;
    global $service_cgi;
    global $slot_filter_state;
    global $service_type_cgi;
    $slots_filters = array();
    foreach ($slot_filter_state as $name => $checked)
        if ($checked)
            array_push($slots_filters, $name);
    $check_conf="";
    if ($slot_filter_state["check_conf"])
        $check_conf="invalid_config_files";
    $req = "dashboard?command=get_info_server&ctype=$ctype_cgi&service=$service_cgi&service_type=$service_type_cgi&min_ok_uptime=$minOkUptime"."s";
    $req .= "&slots_filters=" . implode(",", $slots_filters);
    $req .= "&filter=result.controller_status,result.controller_uptime,result.mem_size_real,result.cpu_load_user,result.cpu_load_system,";
    $req .= "id,$check_conf,result.slot.container.constraints.cpu_policy,result.slot.container.constraints.cpu_limit,result.slot.container.constraints.cpu_guarantee,";
    $req .= "result.config.DaemonConfig.[0].Controller.[0].DMOptions.[0].CType,result.config.DaemonConfig.[0].Controller.[0].DMOptions.[0].ServiceType,";
    $req .= "result.slot.container.constraints.memory_limit";
    $req .= "&groupings=\$datacenter\$;host(result.load_average,result.cpu_count,result.total_mem_size)";
    read_reply_from_dm($req, $json_free_cluster_data);
    $cluster_free_info = json_decode($json_free_cluster_data, true);
    if (count($cluster_free_info) == 0)
        return "";
    $free_cluster_report = "<table class='cluster_structure' ><tr>";
    $iterators = array();
    usort($cluster_free_info, "compare_id");
    $ci_sorted = array();
    foreach ($cluster_free_info as $dc) {
        $slot_count = 0;
        $host_count = 0;
        $hosts_sorted = array();
        foreach ($dc["hosts"] as $host) {
            $slots = $host["slots"];
            usort($slots, "compare_id");
            $host_count++;
            $slot_count += count($slots);
            $new_host = $host;
            $new_host["slots"] = $slots;
            array_push($hosts_sorted, $new_host);
        }
        usort($hosts_sorted, "compare_id");
        $dc_name = $dc["id"];
        $free_cluster_report .= "<td>$dc_name ($host_count / $slot_count)</td>";
        array_push($iterators, new ArrayIterator($hosts_sorted));
    }
    $free_cluster_report .= "</tr>";

    $finished = false;
    while (!$finished) {
        $finished = true;
        $free_cluster_report .= "<tr>";

        foreach ($iterators as $iter) {
            $free_cluster_report .= "<td valign=top>";
            if ($iter->valid()) {
                $finished = false;
                $host = $iter->current();
                $service_cells = "";
                $host_guarantee = 0;
                foreach ($host["slots"] as $slot) {
                    $title= htmlentities(json_encode($slot));
                    $service=$slot["service"];
                    $st=$slot["result.controller_status"];
                    $bgcolor = 0x00ff00;
                    $status = "";
                    $hard_info = "";
                    $service_href = $service;
                    if ($service == "unused")
                        $bgcolor = 0xcccccc;
                    if ($st != "Active") {
                        if ($st != "Down") {
                            $status = $st;
                            $bgcolor = 0xffff00;
                        } else {
                            $bgcolor = 0xff0000;
                        }
                    };
                    if ($st != "Down") {
                        $service_href = get_service_href_html($slot, $service);
                        $cpu = $slot["result.cpu_load_user"] + $slot["result.cpu_load_system"];
                        $cpu_limit = $cc * 100;
                        if ($slot["result.slot.container.constraints.cpu_policy"] === "normal") {
                            $cpu_limit = (int)((float)$slot["result.slot.container.constraints.cpu_limit"] * 100);
                            $cpu_color = " style='background-color:#ffff00'";
                        }
                        $cpu_guarantee = (float)$slot["result.slot.container.constraints.cpu_guarantee"];
                        $host_guarantee += $cpu_guarantee;
                        $cpu_guarantee_perc =(int)($cpu_guarantee * 100);
                        $cpu_usage_color = get_limited_color($cpu, $cpu_limit, 0.5, 0xffff00);
                        $mem_limit = (int)(float)$slot["result.slot.container.constraints.memory_limit"];
                        $mem_used = (int)(float)$slot["result.mem_size_real"];
                        $mem_color = get_limited_color($mem_used * 1024 * 1024, $mem_limit, 0.7, 0xffff00);
                        if ($mem_limit <= 10 * 1024 * 1024 * 1024 && $mem_used <= 16384) {
                            $mem_limit = (int)($mem_limit / (1024 * 1024));
                            $mem_unit = "Mb";
                        } else {
                            $mem_limit = (int)($mem_limit / (1024 * 1024 * 1024));
                            $mem_used = (int)($mem_used / 1024);
                            $mem_unit = "Gb";
                        }
                        $hard_info = ", <span$mem_color>$mem_used/$mem_limit$mem_unit</span>, <span$cpu_usage_color>" . $slot["result.cpu_load_user"] . "/$cpu</span>/ <span $cpu_color>$cpu_limit</span>($cpu_guarantee_perc) %";
                        $uptime = (int)$slot["result.controller_uptime"];
                        $uptime_color = $uptime < $minOkUptime ? " style='background-color:#ff0000'" : "";
                        $hard_info .= ", <span$uptime_color>" . $uptime . "s</span>";
                        if (array_key_exists("invalid_config_files", $slot) && is_array($slot["invalid_config_files"])) {
                            $status .= ($status == "" ? "" : ",") . Cfg;
                            $bgcolor = 0xffff00;
                        }
                    }
                    if ($service != $service_cgi)
                        $bgcolor = $bgcolor | 0xdddddd;
                    if ($status != "")
                        $status = "(" . $status . ")";
                    $text="$service_href$status$hard_info";
                    $host_port = explode(":", $slot["id"]);
                    $port = $host_port[1];
                    $controller = $host_port[0] . ":" . ((int)$port + 3);
                    $service_cells .= "<tr><td title=$title style='background-color:#" . sprintf("%06X",$bgcolor) . "'><a href='http://$controller?command=get_info_server' target='_blank'>$port</a>: $text</td></tr>";
                }

                $tms = (int)($host["result.total_mem_size"] / (1024 * 1024 * 1024));
                $cc = $host["result.cpu_count"];
                if ($cc == 0)
                    $cc = 10;
                $la = $host["result.load_average"];

                $host_info = explode(".", $host["id"])[0];

                $host_guarantee_str = round($host_guarantee, 2);
                $host_info .= ", $cc($host_guarantee_str)" . "cpu, $tms" . "Gb";
                $lacolor = get_limited_color(0.33 * $la, $cc, 0, 0xffffff);
                $host_info .= ", <span$lacolor>la $la</span>";

                $free_cluster_report .= "<table border=\"0\" frame=void cellspacing=\"0\" cellpadding=\"0\" width=\"100%\"><tr><td align=center><b>$host_info</b></td></tr>";
                $free_cluster_report .= $service_cells;
                $free_cluster_report .= "</table>";
            }
            $free_cluster_report .= "</td>";
            $iter->next();
        }
        $free_cluster_report .= "</tr>";
    }

    return $free_cluster_report;
}

function get_url() {
    $result = parse_url($_SERVER['REQUEST_URI'])["path"] . "?";
    global $check_boxs;
    $filter = array();
    foreach ($check_boxs as $cb)
        array_push($filter, $cb["name"]);
    foreach ($_GET as $key => $value) {
        if (!in_array($key, $filter))
            $result .= "&$key=$value";
    }
    return $result;
}

function renderClusterReport() {
    global $service_cgi;
    global $service_type;
    global $slot_filter_state;
    global $check_boxs;

    $report_cluster = "";
    $proxy = $service_cgi == "searchproxy" || $service_cgi == "indexerproxy" || $service_type == "intsearch";
    foreach($check_boxs as $cb)
        if (!$proxy || array_key_exists("show_for_proxy", $cb) && $cb["show_for_proxy"])
            $report_cluster .= "<label><input id=\"" . $cb["name"] . "_cb\" type=\"checkbox\" onclick=\"onFilterCheckboxClick('" . get_url() . "')\"" .
            ($slot_filter_state[$cb["name"]] ? " checked=1" : "") . "/>" . $cb["caption"] . "</label>";

    $report_cluster .= " <label><input id='min_ok_uptime_sec' type='number' step='10' value='600'/> Минимальный Uptime (сек)</label>";

    $report_cluster .= "<p>Cluster structure</p>";
    $report_cluster .= "<div id=\"free_cluster_structure\">";
    $report_cluster .= build_free_cluster_structure(600);
    $report_cluster .= "</div>";
    return $report_cluster;
}

$koolajax->scriptFolder = $KoolControlsFolder . "/KoolAjax";
$koolajax->enableFunction("build_free_cluster_structure");

include("check_task.php")
?>
