import*as Common from"../common/common.js";import*as Host from"../host/host.js";import*as ProtocolClient from"../protocol_client/protocol_client.js";import*as Root from"../root/root.js";import{TargetManager}from"./SDKModel.js";export class MainConnection{constructor(){this._onMessage=null,this._onDisconnect=null,this._messageBuffer="",this._messageSize=0,this._eventListeners=[Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(Host.InspectorFrontendHostAPI.Events.DispatchMessage,this._dispatchMessage,this),Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(Host.InspectorFrontendHostAPI.Events.DispatchMessageChunk,this._dispatchMessageChunk,this)]}setOnMessage(s){this._onMessage=s}setOnDisconnect(s){this._onDisconnect=s}sendRawMessage(s){this._onMessage&&Host.InspectorFrontendHost.InspectorFrontendHostInstance.sendMessageToBackend(s)}_dispatchMessage(s){this._onMessage&&this._onMessage.call(null,s.data)}_dispatchMessageChunk(s){const n=s.data.messageChunk,e=s.data.messageSize;e&&(this._messageBuffer="",this._messageSize=e),this._messageBuffer+=n,this._messageBuffer.length===this._messageSize&&this._onMessage&&(this._onMessage.call(null,this._messageBuffer),this._messageBuffer="",this._messageSize=0)}async disconnect(){const s=this._onDisconnect;Common.EventTarget.EventTarget.removeEventListeners(this._eventListeners),this._onDisconnect=null,this._onMessage=null,s&&s.call(null,"force disconnect")}}export class WebSocketConnection{constructor(s,n){this._socket=new WebSocket(s),this._socket.onerror=this._onError.bind(this),this._socket.onopen=this._onOpen.bind(this),this._socket.onmessage=s=>{this._onMessage&&this._onMessage.call(null,s.data)},this._socket.onclose=this._onClose.bind(this),this._onMessage=null,this._onDisconnect=null,this._onWebSocketDisconnect=n,this._connected=!1,this._messages=[]}setOnMessage(s){this._onMessage=s}setOnDisconnect(s){this._onDisconnect=s}_onError(){this._onWebSocketDisconnect&&this._onWebSocketDisconnect.call(null),this._onDisconnect&&this._onDisconnect.call(null,"connection failed"),this._close()}_onOpen(){if(this._connected=!0,this._socket){this._socket.onerror=console.error;for(const s of this._messages)this._socket.send(s)}this._messages=[]}_onClose(){this._onWebSocketDisconnect&&this._onWebSocketDisconnect.call(null),this._onDisconnect&&this._onDisconnect.call(null,"websocket closed"),this._close()}_close(s){this._socket&&(this._socket.onerror=null,this._socket.onopen=null,this._socket.onclose=s||null,this._socket.onmessage=null,this._socket.close(),this._socket=null),this._onWebSocketDisconnect=null}sendRawMessage(s){this._connected&&this._socket?this._socket.send(s):this._messages.push(s)}disconnect(){return new Promise((s=>{this._close((()=>{this._onDisconnect&&this._onDisconnect.call(null,"force disconnect"),s()}))}))}}export class StubConnection{constructor(){this._onMessage=null,this._onDisconnect=null}setOnMessage(s){this._onMessage=s}setOnDisconnect(s){this._onDisconnect=s}sendRawMessage(s){setTimeout(this._respondWithError.bind(this,s),0)}_respondWithError(s){const n=JSON.parse(s),e={message:"This is a stub connection, can't dispatch message.",code:ProtocolClient.InspectorBackend.DevToolsStubErrorCode,data:n};this._onMessage&&this._onMessage.call(null,{id:n.id,error:e})}async disconnect(){this._onDisconnect&&this._onDisconnect.call(null,"force disconnect"),this._onDisconnect=null,this._onMessage=null}}export class ParallelConnection{constructor(s,n){this._connection=s,this._sessionId=n,this._onMessage=null,this._onDisconnect=null}setOnMessage(s){this._onMessage=s}setOnDisconnect(s){this._onDisconnect=s}sendRawMessage(s){const n=JSON.parse(s);n.sessionId||(n.sessionId=this._sessionId),this._connection.sendRawMessage(JSON.stringify(n))}async disconnect(){this._onDisconnect&&this._onDisconnect.call(null,"force disconnect"),this._onDisconnect=null,this._onMessage=null}}export async function initMainConnection(s,n){ProtocolClient.InspectorBackend.Connection.setFactory(_createMainConnection.bind(null,n)),await s(),Host.InspectorFrontendHost.InspectorFrontendHostInstance.connectionReady(),Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(Host.InspectorFrontendHostAPI.Events.ReattachMainTarget,(()=>{const n=TargetManager.instance().mainTarget();if(n){const s=n.router();s&&s.connection().disconnect()}s()}))}export function _createMainConnection(s){const n=Root.Runtime.Runtime.queryParam("ws"),e=Root.Runtime.Runtime.queryParam("wss");if(n||e){return new WebSocketConnection(n?`ws://${n}`:`wss://${e}`,s)}return Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode()?new StubConnection:new MainConnection}