"use strict";

const net = require("node:net");

const SOCKET_PATH = process.env.LAKE_LAMP_ACTION_SOCKET || "/run/guanghu/action-broker.sock";
const OWNER_ACCESS_SOCKET_PATH = process.env.LAKE_LAMP_OWNER_ACCESS_SOCKET || "/run/guanghu-owner-access/owner-access.sock";
const ARCHITECTURE_PROVISION_SOCKET_PATH = process.env.LAKE_LAMP_ARCHITECTURE_PROVISION_SOCKET || "/run/guanghu-architecture-provision/provision.sock";

function executeRegisteredAction(request, socketPath) {
  const ownerAccessActions = new Set([
    "restore-owner-password-login",
    "restore-code-channel-owner-login",
  ]);
  const selectedSocket = socketPath || (ownerAccessActions.has(request.action) ? OWNER_ACCESS_SOCKET_PATH : request.action === "provision-approved-architecture" ? ARCHITECTURE_PROVISION_SOCKET_PATH : SOCKET_PATH);
  return new Promise((resolve) => {
    const socket = net.createConnection(selectedSocket);
    let response = "";
    let settled = false;
    const finish = (value) => { if (!settled) { settled = true; resolve(value); } };
    socket.setTimeout(request.action === "provision-approved-architecture" ? 150000 : 35000);
    socket.on("connect", () => socket.end(`${JSON.stringify(request)}\n`));
    socket.on("data", chunk => { response += chunk.toString("utf8"); if (response.length > 100000) socket.destroy(); });
    socket.on("end", () => {
      try { finish(JSON.parse(response)); } catch { finish({ ok: false, error: "invalid_broker_response" }); }
    });
    socket.on("timeout", () => { socket.destroy(); finish({ ok: false, error: "action_timeout" }); });
    socket.on("error", () => finish({ ok: false, error: "action_broker_unavailable" }));
  });
}

module.exports = { executeRegisteredAction, SOCKET_PATH, OWNER_ACCESS_SOCKET_PATH, ARCHITECTURE_PROVISION_SOCKET_PATH };
