
import { CLOUD_API_SERVICE_ID } from "../audit/index.mjs";
import { ERROR_CODES } from "../protocol/index.mjs";
import { M3_IO_CONTROL_ROUTE, handleM3IoControl } from "./m3-io-control.ts";
import { getHeader, readBody, sendJson } from "./server-http-utils.ts";

export async function handleM3IoControlHttp(request, response, options) {
  const body = await readBody(request, options.bodyLimitBytes);
  let params = {};

  try {
    params = body ? JSON.parse(body) : {};
  } catch (error) {
    sendJson(response, 400, {
      serviceId: CLOUD_API_SERVICE_ID,
      contractVersion: "m3-io-control-v1",
      route: M3_IO_CONTROL_ROUTE,
      method: "POST",
      status: "blocked",
      accepted: false,
      traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
      operationId: null,
      auditId: null,
      evidenceId: null,
      audit: {
        auditId: null,
        status: "not_written"
      },
      evidence: {
        evidenceId: null,
        status: "blocked",
        sourceKind: "BLOCKED"
      },
      readback: null,
      error: {
        code: "parse_error",
        message: "Invalid JSON body",
        reason: error.message
      }
    });
    return;
  }

  if (!params || typeof params !== "object" || Array.isArray(params)) {
    sendJson(response, 400, {
      serviceId: CLOUD_API_SERVICE_ID,
      contractVersion: "m3-io-control-v1",
      route: M3_IO_CONTROL_ROUTE,
      method: "POST",
      status: "blocked",
      accepted: false,
      traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
      operationId: null,
      auditId: null,
      evidenceId: null,
      audit: {
        auditId: null,
        status: "not_written"
      },
      evidence: {
        evidenceId: null,
        status: "blocked",
        sourceKind: "BLOCKED"
      },
      readback: null,
      error: {
        code: "invalid_params",
        message: "M3 IO control body must be a JSON object"
      }
    });
    return;
  }

  try {
    const payload = await handleM3IoControl(
      {
        ...params,
        traceId: getHeader(request, "x-trace-id") || params.traceId,
        requestId: getHeader(request, "x-request-id") || params.requestId,
        actorId: getHeader(request, "x-actor-id") || params.actorId
      },
      {
        runtimeStore: options.runtimeStore,
        env: options.env,
        requestJson: options.m3IoRequestJson,
        traceId: getHeader(request, "x-trace-id"),
        requestId: getHeader(request, "x-request-id"),
        actorId: getHeader(request, "x-actor-id")
      }
    );
    sendJson(response, payload.httpStatus ?? 200, payload);
  } catch (error) {
    const protocolCode = Number.isInteger(error?.code) ? error.code : ERROR_CODES.internalError;
    sendJson(response, protocolCode === ERROR_CODES.invalidParams ? 400 : 200, {
      serviceId: CLOUD_API_SERVICE_ID,
      contractVersion: "m3-io-control-v1",
      route: M3_IO_CONTROL_ROUTE,
      method: "POST",
      status: "blocked",
      accepted: false,
      traceId: getHeader(request, "x-trace-id") || params.traceId || "trc_unassigned",
      operationId: null,
      auditId: null,
      evidenceId: null,
      audit: {
        auditId: null,
        status: "not_written"
      },
      evidence: {
        evidenceId: null,
        status: "blocked",
        sourceKind: "BLOCKED"
      },
      readback: null,
      error: {
        code: protocolCode,
        message: error.message,
        data: error.data ?? {}
      }
    });
  }
}
