<script>
    import { init, checkMetricDisabled } from "./utils.js";
    import {
        Row,
        Col,
        InputGroup,
        InputGroupText,
        Icon,
        Spinner,
        Card,
    } from "sveltestrap";
    import { queryStore, gql, getContextClient } from "@urql/svelte";
    import TimeSelection from "./filters/TimeSelection.svelte";
    import PlotTable from "./PlotTable.svelte";
    import MetricPlot from "./plots/MetricPlot.svelte";
    import { getContext } from "svelte";

    export let cluster;
    export let hostname;
    export let from = null;
    export let to = null;

    const { query: initq } = init();

    if (from == null || to == null) {
        to = new Date(Date.now());
        from = new Date(to.getTime());
        from.setMinutes(from.getMinutes() - 30);
    }

    const ccconfig = getContext("cc-config");
    const clusters = getContext("clusters");
    const client = getContextClient();
    const nodeMetricsQuery = gql`
        query ($cluster: String!, $nodes: [String!], $from: Time!, $to: Time!) {
            nodeMetrics(
                cluster: $cluster
                nodes: $nodes
                from: $from
                to: $to
            ) {
                host
                subCluster
                metrics {
                    name
                    scope
                    metric {
                        timestep
                        unit {
                            base
                            prefix
                        }
                        series {
                            statistics {
                                min
                                avg
                                max
                            }
                            data
                        }
                    }
                }
            }
        }
    `;

    $: nodeMetricsData = queryStore({
        client: client,
        query: nodeMetricsQuery,
        variables: {
            cluster: cluster,
            nodes: [hostname],
            from: from.toISOString(),
            to: to.toISOString(),
        },
    });

    let itemsPerPage = ccconfig.plot_list_jobsPerPage;
    let page = 1;
    let paging = { itemsPerPage, page };
    let sorting = { field: "startTime", order: "DESC" };
    $: filter = [
        { cluster: { eq: cluster } },
        { node: { contains: hostname } },
        { state: ["running"] },
        // {startTime: {
        //     from: from.toISOString(),
        //     to: to.toISOString()
        // }}
    ];

    const nodeJobsQuery = gql`
        query (
            $filter: [JobFilter!]!
            $sorting: OrderByInput!
            $paging: PageRequest!
        ) {
            jobs(filter: $filter, order: $sorting, page: $paging) {
                # items {
                #     id
                #     jobId
                # }
                count
            }
        }
    `;

    $: nodeJobsData = queryStore({
        client: client,
        query: nodeJobsQuery,
        variables: { paging, sorting, filter },
    });

    let metricUnits = {};
    $: if ($nodeMetricsData.data) {
        let thisCluster = clusters.find((c) => c.name == cluster);
        if (thisCluster) {
            for (let metric of thisCluster.metricConfig) {
                if (metric.unit.prefix || metric.unit.base) {
                    metricUnits[metric.name] =
                        "(" +
                        (metric.unit.prefix ? metric.unit.prefix : "") +
                        (metric.unit.base ? metric.unit.base : "") +
                        ")";
                } else {
                    // If no unit defined: Omit Unit Display
                    metricUnits[metric.name] = "";
                }
            }
        }
    }

    const dateToUnixEpoch = (rfc3339) => Math.floor(Date.parse(rfc3339) / 1000);
</script>

<Row>
    {#if $initq.error}
        <Card body color="danger">{$initq.error.message}</Card>
    {:else if $initq.fetching}
        <Spinner />
    {:else}
        <Col>
            <InputGroup>
                <InputGroupText><Icon name="hdd" /></InputGroupText>
                <InputGroupText>{hostname} ({cluster})</InputGroupText>
            </InputGroup>
        </Col>
        <Col>
            {#if $nodeJobsData.fetching}
                <Spinner />
            {:else if $nodeJobsData.data}
                Currently running jobs on this node: {$nodeJobsData.data.jobs
                    .count}
                [
                <a
                    href="/monitoring/jobs/?cluster={cluster}&state=running&node={hostname}"
                    target="_blank">View in Job List</a
                > ]
            {:else}
                No currently running jobs.
            {/if}
        </Col>
        <Col>
            <TimeSelection bind:from bind:to />
        </Col>
    {/if}
</Row>
<br />
<Row>
    <Col>
        {#if $nodeMetricsData.error}
            <Card body color="danger">{$nodeMetricsData.error.message}</Card>
        {:else if $nodeMetricsData.fetching || $initq.fetching}
            <Spinner />
        {:else}
            <PlotTable
                let:item
                let:width
                renderFor="node"
                itemsPerRow={ccconfig.plot_view_plotsPerRow}
                items={$nodeMetricsData.data.nodeMetrics[0].metrics
                    .map((m) => ({
                        ...m,
                        disabled: checkMetricDisabled(
                            m.name,
                            cluster,
                            $nodeMetricsData.data.nodeMetrics[0].subCluster
                        ),
                    }))
                    .sort((a, b) => a.name.localeCompare(b.name))}
            >
                <h4 style="text-align: center; padding-top:15px;">
                    {item.name}
                    {metricUnits[item.name]}
                </h4>
                {#if item.disabled === false && item.metric}
                    <MetricPlot
                        {width}
                        height={300}
                        metric={item.name}
                        timestep={item.metric.timestep}
                        cluster={clusters.find((c) => c.name == cluster)}
                        subCluster={$nodeMetricsData.data.nodeMetrics[0]
                            .subCluster}
                        series={item.metric.series}
                        resources={[{hostname: hostname}]}
                    />
                {:else if item.disabled === true && item.metric}
                    <Card
                        style="margin-left: 2rem;margin-right: 2rem;"
                        body
                        color="info"
                        >Metric disabled for subcluster <code
                            >{item.name}:{$nodeMetricsData.data.nodeMetrics[0]
                                .subCluster}</code
                        ></Card
                    >
                {:else}
                    <Card
                        style="margin-left: 2rem;margin-right: 2rem;"
                        body
                        color="warning"
                        >No dataset returned for <code>{item.name}</code></Card
                    >
                {/if}
            </PlotTable>
        {/if}
    </Col>
</Row>
