import { Type } from "@sinclair/typebox";

import type { CheckerSchemas } from "../types";

import {
  createAuthoringFieldSchema,
  createAuthoringValueExpectationSchema,
  createNormalizedValueExpectationSchema,
} from "../../schema/fragments";

export const icmpCheckerSchemas: CheckerSchemas = {
  authoring: {
    config: createIcmpConfigSchema("authoring"),
    expect: createIcmpExpectSchema("authoring"),
  },
  normalized: {
    config: createIcmpConfigSchema("normalized"),
    expect: createIcmpExpectSchema("normalized"),
  },
};

function createIcmpConfigSchema(kind: "authoring" | "normalized") {
  const count = Type.Integer({ maximum: 100, minimum: 1 });
  const packetSize = Type.Integer({ maximum: 65500, minimum: 1 });
  return Type.Object(
    {
      count: Type.Optional(kind === "authoring" ? createAuthoringFieldSchema(count) : count),
      host: Type.String({ minLength: 1 }),
      packetSize: Type.Optional(kind === "authoring" ? createAuthoringFieldSchema(packetSize) : packetSize),
    },
    { additionalProperties: false },
  );
}

function createIcmpExpectSchema(kind: "authoring" | "normalized") {
  const bool = Type.Boolean();
  return Type.Object(
    {
      alive: Type.Optional(kind === "authoring" ? createAuthoringFieldSchema(bool) : bool),
      avgLatencyMs: Type.Optional(
        kind === "authoring" ? createAuthoringValueExpectationSchema() : createNormalizedValueExpectationSchema(),
      ),
      durationMs: Type.Optional(
        kind === "authoring" ? createAuthoringValueExpectationSchema() : createNormalizedValueExpectationSchema(),
      ),
      maxLatencyMs: Type.Optional(
        kind === "authoring" ? createAuthoringValueExpectationSchema() : createNormalizedValueExpectationSchema(),
      ),
      packetLossPercent: Type.Optional(
        kind === "authoring" ? createAuthoringValueExpectationSchema() : createNormalizedValueExpectationSchema(),
      ),
    },
    { additionalProperties: false },
  );
}
