//
// Copyright 2020 DXOS.org
//
import { formatDistance } from 'date-fns';
import React, { useEffect, useMemo, useState } from 'react';
import { scheduleTaskInterval } from '@dxos/async';
import { Context } from '@dxos/context';
import { Format } from '@dxos/echo/internal';
import { SignalState } from '@dxos/protocols/proto/dxos/mesh/signal';
import { useDevtools, useStream } from '@dxos/react-client/devtools';
import { DynamicTable } from '@dxos/react-ui-table';
const getSignalStatus = (server) => {
    return {
        connectionStarted: server.connectionStarted,
        lastStateChange: server.lastStateChange,
        reconnectIn: server.reconnectIn,
        host: server.host,
        state: server.state,
    };
};
const signalStateLabels = {
    [SignalState.CONNECTING]: 'CONNECTING',
    [SignalState.RECONNECTING]: 'RECONNECTING',
    [SignalState.CONNECTED]: 'CONNECTED',
    [SignalState.DISCONNECTED]: 'DISCONNECTED',
    [SignalState.ERROR]: 'ERROR',
    [SignalState.CLOSED]: 'CLOSED',
    UNKNOWN: 'UNKNOWN',
};
const stateColors = {
    CONNECTING: 'orange',
    RECONNECTING: 'orange',
    CONNECTED: 'green',
    DISCONNECTED: 'orange',
    ERROR: 'red',
    CLOSED: 'neutral',
    UNKNOWN: 'neutral',
};
const getStateLabel = (state) => {
    return signalStateLabels[state] ?? 'UNKNOWN';
};
const tableProperties = [
    {
        name: 'host',
        format: Format.TypeFormat.String,
        size: 240,
    },
    {
        name: 'status',
        format: Format.TypeFormat.SingleSelect,
        size: 140,
        config: {
            options: Object.values(signalStateLabels).map((label) => ({
                id: label,
                title: label,
                color: stateColors[label],
            })),
        },
    },
    {
        name: 'connected',
        format: Format.TypeFormat.String,
        size: 240,
    },
];
export const SignalStatusTable = () => {
    const devtoolsHost = useDevtools();
    const { servers } = useStream(() => devtoolsHost.subscribeToSignalStatus(), { servers: [] });
    const status = servers.map(getSignalStatus);
    const [time, setTime] = useState(new Date());
    useEffect(() => {
        const ctx = new Context();
        scheduleTaskInterval(ctx, async () => {
            setTime(new Date());
        }, 1000);
        return () => {
            void ctx.dispose();
        };
    }, []);
    if (!servers) {
        return null;
    }
    const properties = useMemo(() => tableProperties, []);
    const rows = useMemo(() => {
        return status.map((status, index) => ({
            id: `${index}-${status.host}`,
            host: new URL(status.host).origin,
            status: getStateLabel(status.state),
            connected: status.state === SignalState.CONNECTED
                ? formatDistance(status.lastStateChange.getTime(), time.getTime(), { includeSeconds: true, addSuffix: true })
                : `Reconnecting ${formatDistance(time.getTime(), status.lastStateChange.getTime() + status.reconnectIn, {
                    addSuffix: true,
                })}`,
            _original: status,
        }));
    }, [status, time]);
    return React.createElement(DynamicTable, { properties: properties, rows: rows });
};
//# sourceMappingURL=SignalStatusTable.js.map