import { describe, expect, test } from "vitest";
import { WebSocket } from "ws";

import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
import {
  connectOk,
  installGatewayTestHooks,
  rpcReq,
  startServerWithClient,
} from "./test-helpers.js";

installGatewayTestHooks();

describe("gateway role enforcement", () => {
  test("enforces operator and node permissions", async () => {
    const { server, ws, port } = await startServerWithClient();
    await connectOk(ws);

    const eventRes = await rpcReq(ws, "node.event", { event: "test", payload: { ok: true } });
    expect(eventRes.ok).toBe(false);
    expect(eventRes.error?.message ?? "").toContain("unauthorized role");

    const invokeRes = await rpcReq(ws, "node.invoke.result", {
      id: "invoke-1",
      nodeId: "node-1",
      ok: true,
    });
    expect(invokeRes.ok).toBe(false);
    expect(invokeRes.error?.message ?? "").toContain("unauthorized role");

    const nodeWs = new WebSocket(`ws://127.0.0.1:${port}`);
    await new Promise<void>((resolve) => nodeWs.once("open", resolve));
    await connectOk(nodeWs, {
      role: "node",
      client: {
        id: GATEWAY_CLIENT_NAMES.NODE_HOST,
        version: "1.0.0",
        platform: "ios",
        mode: GATEWAY_CLIENT_MODES.NODE,
      },
      commands: [],
    });

    const binsRes = await rpcReq<{ bins?: unknown[] }>(nodeWs, "skills.bins", {});
    expect(binsRes.ok).toBe(true);
    expect(Array.isArray(binsRes.payload?.bins)).toBe(true);

    const statusRes = await rpcReq(nodeWs, "status", {});
    expect(statusRes.ok).toBe(false);
    expect(statusRes.error?.message ?? "").toContain("unauthorized role");

    nodeWs.close();
    ws.close();
    await server.close();
  });
});
