@using StackExchange.Profiling
@inject IJsonHelper Json
@model DashboardModel
@{
    // Note: not using MVC Url.Action and such here because it's too slow
    Layout = "Dashboard.cshtml";
    var categories = Model.Nodes
                          .GroupBy(n => n.Category)
                          .Where(g => g.Any() && (g.Key != DashboardCategory.Unknown || Module.Settings.ShowOther))
                          .OrderBy(g => g.Key.Index);
}
@section preload {
    @if (Module.HasData && this.SupportsSvgViewport())
    {
        <link rel="preload" href="@Url.Content("~/graph/")cpu/spark/all" as="image">
        <link rel="preload" href="@Url.Content("~/graph/")memory/spark/all" as="image">
        <link rel="preload" href="@Url.Content("~/graph/")network/spark/all" as="image">
    }
}
@functions
{
    string Graph(Node n, string type)
    {
        if (Module.HasData)
        {
            if (this.SupportsSvgViewport())
            {
                <a href="#/dashboard/graph/@(n.Id.UrlEncode())/@type"><img src="@Url.Content("~/graph/")@type/spark/all#@n.Id" alt="" /></a>
            }
            else
            {
                <a href="#/dashboard/graph/@(n.Id.UrlEncode())/@type"><img src="@Url.Content("~/graph/")@type/spark?id=@n.Id" alt="" /></a>
            }
        }
        else
        {
            <div class="text-muted">No Data Available</div>
        }
        return null;
    }

    string DiskText(Node n)
    {
        var worst = n.Volumes?.Where(v => v?.PercentUsed.HasValue ?? false).DefaultIfEmpty().Max(v => v?.PercentUsed);
        if (worst > 0)
        {
            @worst.Value.ToString("n0")@:%
        }
        return null;
    }

    string DiskGraphs(Node n)
    {
        if (n.Volumes != null)
        {
            for (var i = 0; i < n.Volumes.Count && i < 10; i++)
            {
                var vol = n.Volumes[i];
                <div class="progress vertical" title="@vol.PrettyName: @(vol.PercentUsed?.ToString("n2"))% used (@vol.PrettyUsed/@vol.PrettySize)">
                    <div class="progress-bar @vol.SpaceStatus.ProgressBarClass()" style="height: @(vol.PercentUsed?.ToString("n2",CultureInfo.InvariantCulture))%"></div>
                </div>
            }
        }
        return null;
    }
}
<div class="js-refresh" data-name="dashboard-overview">
    @if (!Model.Nodes.Any() || Model.IsStartingUp)
    {
        var errors = Model.ErrorMessages;
        <div class="row">
            <div class="col-md-6 col-md-offset-3 text-center" style="margin-top: 100px">
                @if (Model.IsStartingUp)
                {
                    <h5>No data, yet!</h5>
                    <p class="text-muted small">The initial poll is underway - you'll see nodes appear in just a moment.</p>
                    <div class="sk-wave"><div></div><div></div><div></div><div></div><div></div></div>
                    <script>Status.refresh.schedule(2000);</script>
                }
                else
                {
                    <p>No nodes available</p>
                }
            </div>
        </div>
        if (errors != null && errors.Any())
        {
            <script>
                @foreach (var e in errors)
                {
                    @:toastr.warning('@Json.Serialize(e)', null, { positionClass: "toast-bottom-full-width", timeOut: 60 * 1000 });
                }
            </script>
        }
    }
    else
    {
        <table class="table table-striped table-responsive table-middle table-super-condensed table-dashboard text-nowrap js-nodes">
            @foreach (var g in categories)
            {
                var c = g.Key;
                using (MiniProfiler.Current.Step("Category: " + c.Name))
                {
                    <tbody>
                        <tr class="category-row">
                            <th colspan="9">
                                <h5>@c.Name</h5>
                            </th>
                        </tr>
                        <tr>
                            <th>Node</th>
                            <th colspan="2">CPU</th>
                            <th colspan="2">Memory</th>
                            <th colspan="2">Network</th>
                            @if (Module.Settings.ShowVolumePerformance)
                            {
                                <th colspan="2">Disk (Perf)</th>
                            }
                            <th colspan="2">Disk</th>
                        </tr>
                        @foreach (var n in g.OrderBy(n => n.PrettyName))
                        {
                            <tr class="@(n.RowClass().Nullify())@(n.IsVM ? " virtual-machine" : null)@(n.IsUnwatched ? " unwatched-row" : null)" data-node="@n.PrettyName">
                                <td title="@(n.IsVM ? "Virtual Machine hosted on " + (n.VMHost?.PrettyName ?? "Unknown") + " " : null)Last Updated: @(n.LastSync?.ToRelativeTime())">
                                    @n.IconSpan()
                                    <a href="~/dashboard/node?node=@n.PrettyName" class="@n.TextClass().Nullify()">@n.PrettyName</a>
                                </td>
                                <td class="@n.CPUMonitorStatus().TextClass().Nullify()">@(n.CPULoad?.ToString("n0")) %</td>
                                <td>@Graph(n, "cpu")</td>
                                <td>
                                    <span class="@n.MemoryMonitorStatus().TextClass().Nullify()">@n.PrettyMemoryUsed() / @n.PrettyTotalMemory() (@(n.PercentMemoryUsed?.ToString("n2"))%)</span>
                                    @if (n.MemoryUsed >= 0)
                                    {
                                        <div class="progress" style="width: 215px;">
                                            <div class="progress-bar @n.MemoryMonitorStatus().ProgressBarClass()" style="width: @(n.PercentMemoryUsed?.ToString("n2",CultureInfo.InvariantCulture))%"></div>
                                        </div>
                                    }
                                </td>
                                <td>@Graph(n, "memory")</td>
                                <td>@n.PrettyTotalNetwork()</td>
                                <td>@Graph(n, "network")</td>
                                @if (Module.Settings.ShowVolumePerformance)
                                {
                                    <td>@n.PrettyTotalVolumePerformance()</td>
                                    <td>@Graph(n, "volumePerformance")</td>
                                }
                                <td>@DiskText(n)</td>
                                <td>@DiskGraphs(n)</td>
                            </tr>
                        }
                    </tbody>
                }
            }
        </table>
    }
</div>