#!/usr/bin/env node
import {
  handleBoxInvoke,
  operationContext,
  readBoxPort,
  writeBoxPort
} from "../../internal/sim/l2-runtime.mjs";
import { createHealth, createBoxState, selectInstanceValue } from "../../internal/sim/model.mjs";
import { createJsonServer, listen, parsePort, readJson } from "../../internal/sim/http.mjs";

const boxId = selectInstanceValue(process.env.HWLAB_BOX_ID, "boxsim_alpha", {
  requireIndexForMultiple: true,
  label: "HWLAB_BOX_ID"
});
const gatewaySessionId = selectInstanceValue(
  process.env.HWLAB_GATEWAY_SESSION_ID,
  "gws_mvp_simu",
  {
    requireIndexForMultiple: true,
    label: "HWLAB_GATEWAY_SESSION_ID"
  }
);
const resourceId = selectInstanceValue(process.env.HWLAB_BOX_RESOURCE_ID, "", {
  requireIndexForMultiple: true,
  label: "HWLAB_BOX_RESOURCE_ID"
});
const port = parsePort(process.env.PORT, 7201);
const state = createBoxState({ boxId, gatewaySessionId });
if (resourceId) {
  state.resource.resourceId = resourceId;
  for (const capability of state.capabilities ?? []) {
    capability.resourceId = resourceId;
  }
}

const routes = new Map();

routes.set("GET /health/live", () => ({
  ...createHealth({ serviceId: "hwlab-box-simu", name: boxId }),
  boxId,
  resourceId: state.resource.resourceId
}));
routes.set("GET /status", () => state);
routes.set("GET /capabilities", () => ({
  serviceId: "hwlab-box-simu",
  boxId,
  resourceId: state.resource.resourceId,
  capabilities: state.capabilities
}));
routes.set("GET /internal/ports", () => ({
  serviceId: "hwlab-box-simu",
  boxId,
  resourceId: state.resource.resourceId,
  ports: state.ports,
  internalPortApi: true
}));
routes.set("POST /ports/read", async ({ req }) => {
  const body = await readJson(req);
  return readBoxPort({
    state,
    port: body.port,
    capabilityId: body.capabilityId,
    context: operationContext(body, { serviceId: "hwlab-box-simu" })
  });
});
routes.set("POST /ports/write", async ({ req }) => {
  const body = await readJson(req);
  return writeBoxPort({
    state,
    port: body.port,
    capabilityId: body.capabilityId,
    value: body.value,
    source: body.source ?? "local",
    context: operationContext(body, { serviceId: "hwlab-box-simu" })
  });
});
routes.set("POST /internal/ports/write", async ({ req }) => {
  const body = await readJson(req);
  return writeBoxPort({
    state,
    port: body.port,
    capabilityId: body.capabilityId,
    value: body.value,
    source: body.source ?? "internal",
    sourceResourceId: body.sourceResourceId,
    sourcePort: body.sourcePort,
    propagatedBy: body.propagatedBy,
    internal: true,
    context: operationContext(body, { serviceId: "hwlab-box-simu" })
  });
});
routes.set("POST /invoke", async ({ req }) => {
  const body = await readJson(req);
  return handleBoxInvoke({
    state,
    body,
    context: operationContext(body, { serviceId: "hwlab-box-simu" })
  });
});

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