import {Flow} from "../../flow";
import * as React from "react";
import {formatTimeDelta, formatTimeStamp} from "../../utils";

export type TimeStampProps = {
    t: number,
    deltaTo?: number,
    title: string,
}

export function TimeStamp({t, deltaTo, title}: TimeStampProps) {
    return t ? (
        <tr>
            <td>{title}:</td>
            <td>
                {formatTimeStamp(t)}
                {deltaTo && (
                    <span className="text-muted">
                        ({formatTimeDelta(1000 * (t - deltaTo))})
                    </span>
                )}
            </td>
        </tr>
    ) : (
        <tr/>
    )
}

export default function Timing({flow}: { flow: Flow }) {
    let ref: number;
    if (flow.type === "http") {
        ref = flow.request.timestamp_start
    } else {
        ref = flow.client_conn.timestamp_start
    }

    const timestamps: Partial<TimeStampProps>[] = [
        {
            title: "Server conn. initiated",
            t: flow.server_conn?.timestamp_start,
            deltaTo: ref
        }, {
            title: "Server conn. TCP handshake",
            t: flow.server_conn?.timestamp_tcp_setup,
            deltaTo: ref
        }, {
            title: "Server conn. TLS handshake",
            t: flow.server_conn?.timestamp_tls_setup,
            deltaTo: ref
        }, {
            title: "Server conn. closed",
            t: flow.server_conn?.timestamp_end,
            deltaTo: ref
        }, {
            title: "Client conn. established",
            t: flow.client_conn.timestamp_start,
            deltaTo: flow.type === "http" ? ref : undefined
        }, {
            title: "Client conn. TLS handshake",
            t: flow.client_conn.timestamp_tls_setup,
            deltaTo: ref
        }, {
            title: "Client conn. closed",
            t: flow.client_conn.timestamp_end,
            deltaTo: ref
        },
    ]
    if (flow.type === "http") {
        timestamps.push(...[
            {
                title: "First request byte",
                t: flow.request.timestamp_start
            }, {
                title: "Request complete",
                t: flow.request.timestamp_end,
                deltaTo: ref
            }, {
                title: "First response byte",
                t: flow.response?.timestamp_start,
                deltaTo: ref
            }, {
                title: "Response complete",
                t: flow.response?.timestamp_end,
                deltaTo: ref
            }
        ]);
    }

    return (
        <section className="timing">
            <h4>Timing</h4>
            <table className="timing-table">
                <tbody>
                {timestamps
                    .filter((v): v is TimeStampProps => !!v.t)
                    .sort((a, b) => a.t - b.t)
                    .map(props => <TimeStamp key={props.title} {...props}/>)}
                </tbody>
            </table>
        </section>
    )
}
Timing.displayName = "Timing"
