import { Server } from "node:http";
import { WebSocketServer } from "ws";
import { assert } from "../../../shared/src/asserts.js";
import { serializableSubset } from "./http.js";
import "./processes.js";
import { closeWithError, PROTOCOL_ERROR } from "./ws.js";
function createWebSocketHandoffHandler(lc, handoff, serverOptions) {
  const wss = new WebSocketServer(
    {
      noServer: true
    }
  );
  return (message, socket, head) => {
    let sent = false;
    function send({ payload, sender }) {
      assert(!sent, "Handoff callback already invoked");
      sent = true;
      const data = [
        "handoff",
        {
          message: serializableSubset(message),
          head,
          payload
        }
      ];
      sender.send(data, socket);
    }
    function onError(error) {
      wss.handleUpgrade(
        message,
        socket,
        Buffer.from(head),
        (ws) => closeWithError(lc, ws, error, PROTOCOL_ERROR)
      );
    }
    try {
      const spec = handoff(message, send, onError);
      if (spec) {
        send(spec);
      }
    } catch (error) {
      onError(error);
    }
  };
}
function installWebSocketHandoff(lc, handoff, source, serverOptions) {
  const handle = createWebSocketHandoffHandler(lc, handoff);
  if (source instanceof Server) {
    source.on("upgrade", handle);
  } else {
    source.onMessageType("handoff", (msg, socket) => {
      const { message, head } = msg;
      handle(message, socket, head);
    });
  }
}
function installWebSocketReceiver(lc, server, receive, receiver) {
  receiver.onMessageType("handoff", (msg, socket) => {
    if (!socket) {
      lc.warn?.("websocket closed during handoff");
      return;
    }
    const { message, head, payload } = msg;
    server.handleUpgrade(
      message,
      socket,
      Buffer.from(head),
      (ws) => {
        if (ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) {
          lc.warn?.("websocket closed during upgrade, skipping receive");
          return;
        }
        receive(ws, payload, message);
      }
    );
  });
}
export {
  createWebSocketHandoffHandler,
  installWebSocketHandoff,
  installWebSocketReceiver
};
//# sourceMappingURL=websocket-handoff.js.map
