#!/usr/bin/env node
import { createM3Topology } from "../../internal/patchpanel/fixture.mjs";
import {
  createPatchPanelRuntime,
  createPatchPanelRuntimeFromFile
} from "../../internal/patchpanel/runtime.mjs";
import { createHealth } from "../../internal/sim/model.mjs";
import { createJsonServer, listen, parsePort, readJson } from "../../internal/sim/http.mjs";

const port = parsePort(process.env.PORT, 7301);
const wiringConfigPath = process.env.HWLAB_WIRING_CONFIG_PATH;
const topology = createM3Topology();
const endpointMap = parseEndpointMap(process.env.HWLAB_PATCH_PANEL_ENDPOINT_MAP) ?? {
  res_boxsimu_2: "http://hwlab-box-simu-2.hwlab-dev.svc.cluster.local:7201"
};
const manifestWiringConfig = parseWiringConfig(process.env.HWLAB_PATCH_PANEL_WIRING_CONFIG);
const runtime = wiringConfigPath
  ? await createPatchPanelRuntimeFromFile({ path: wiringConfigPath })
  : createPatchPanelRuntime({
      wiringConfig: manifestWiringConfig ?? topology.wiringConfig,
      endpointMap,
      configSource: manifestWiringConfig ? "env:HWLAB_PATCH_PANEL_WIRING_CONFIG" : "internal:m3-topology"
    });

const routes = new Map();

routes.set("GET /health/live", () =>
  createHealth({ serviceId: "hwlab-patch-panel", name: "hwlab-patch-panel" })
);
routes.set("GET /status", () => runtime.status());
routes.set("GET /diagnostics", () => runtime.diagnostics());
routes.set("GET /wiring", () => runtime.wiringConfig);
routes.set("POST /wiring/apply", async ({ req }) => runtime.applyConfig(await readJson(req)));
routes.set("POST /wiring/reload", async ({ req }) => {
  const body = await readJson(req);
  const path = body.path ?? wiringConfigPath;
  if (!path) {
    throw new Error("wiring reload requires body.path or HWLAB_WIRING_CONFIG_PATH");
  }
  return runtime.reloadFromFile(path);
});
routes.set("POST /signals/route", async ({ req }) => runtime.routeSignal(await readJson(req)));
routes.set("POST /sync/tick", async ({ req }) => runtime.tick(await readJson(req)));

listen(createJsonServer({ routes }), port);

function parseEndpointMap(value) {
  const source = String(value ?? "").trim();
  if (!source) {
    return null;
  }

  return JSON.parse(source);
}

function parseWiringConfig(value) {
  const source = String(value ?? "").trim();
  if (!source) {
    return null;
  }

  return JSON.parse(source);
}
