import*as Common from'../common/common.js';import*as Host from'../host/host.js';import*as ProtocolModule from'../protocol/protocol.js';import{ParallelConnection}from'./Connections.js';import{Capability,Events,SDKModel,Target,Type}from'./SDKModel.js';let _lastAnonymousTargetId=0;let _attachCallback;export class ChildTargetManager extends SDKModel{constructor(parentTarget){super(parentTarget);this._targetManager=parentTarget.targetManager();this._parentTarget=parentTarget;this._targetAgent=parentTarget.targetAgent();this._targetInfos=new Map();this._childTargets=new Map();this._parallelConnections=new Map();this._parentTargetId=null;parentTarget.registerTargetDispatcher(this);this._targetAgent.invoke_setAutoAttach({autoAttach:true,waitForDebuggerOnStart:true,flatten:true});if(!parentTarget.parentTarget()&&!Host.InspectorFrontendHost.isUnderTest()){this._targetAgent.setDiscoverTargets(true);this._targetAgent.setRemoteLocations([{host:'localhost',port:9229}]);}}
static install(attachCallback){_attachCallback=attachCallback;SDKModel.register(ChildTargetManager,Capability.Target,true);}
suspendModel(){return this._targetAgent.invoke_setAutoAttach({autoAttach:true,waitForDebuggerOnStart:false,flatten:true});}
resumeModel(){return this._targetAgent.invoke_setAutoAttach({autoAttach:true,waitForDebuggerOnStart:true,flatten:true});}
dispose(){for(const sessionId of this._childTargets.keys()){this.detachedFromTarget(sessionId,undefined);}}
targetCreated(targetInfo){this._targetInfos.set(targetInfo.targetId,targetInfo);this._fireAvailableTargetsChanged();}
targetInfoChanged(targetInfo){this._targetInfos.set(targetInfo.targetId,targetInfo);this._fireAvailableTargetsChanged();}
targetDestroyed(targetId){this._targetInfos.delete(targetId);this._fireAvailableTargetsChanged();}
targetCrashed(targetId,status,errorCode){}
_fireAvailableTargetsChanged(){self.SDK.targetManager.dispatchEventToListeners(Events.AvailableTargetsChanged,this._targetInfos.valuesArray());}
async _getParentTargetId(){if(!this._parentTargetId){this._parentTargetId=(await this._parentTarget.targetAgent().getTargetInfo()).targetId;}
return this._parentTargetId;}
attachedToTarget(sessionId,targetInfo,waitingForDebugger){if(this._parentTargetId===targetInfo.targetId){return;}
let targetName='';if(targetInfo.type==='worker'&&targetInfo.title&&targetInfo.title!==targetInfo.url){targetName=targetInfo.title;}else if(targetInfo.type!=='iframe'){const parsedURL=Common.ParsedURL.ParsedURL.fromString(targetInfo.url);targetName=parsedURL?parsedURL.lastPathComponentWithFragment():'#'+(++_lastAnonymousTargetId);}
let type=Type.Browser;if(targetInfo.type==='iframe'){type=Type.Frame;}
else if(targetInfo.type==='page'){type=Type.Frame;}else if(targetInfo.type==='worker'){type=Type.Worker;}else if(targetInfo.type==='service_worker'){type=Type.ServiceWorker;}
const target=this._targetManager.createTarget(targetInfo.targetId,targetName,type,this._parentTarget,sessionId);this._childTargets.set(sessionId,target);if(_attachCallback){_attachCallback({target,waitingForDebugger}).then(()=>{target.runtimeAgent().runIfWaitingForDebugger();});}else{target.runtimeAgent().runIfWaitingForDebugger();}}
detachedFromTarget(sessionId,childTargetId){if(this._parallelConnections.has(sessionId)){this._parallelConnections.delete(sessionId);}else{this._childTargets.get(sessionId).dispose('target terminated');this._childTargets.delete(sessionId);}}
receivedMessageFromTarget(sessionId,message,childTargetId){}
async createParallelConnection(onMessage){const targetId=await this._getParentTargetId();const{connection,sessionId}=await this._createParallelConnectionAndSessionForTarget(this._parentTarget,targetId);connection.setOnMessage(onMessage);this._parallelConnections.set(sessionId,connection);return connection;}
async _createParallelConnectionAndSessionForTarget(target,targetId){const targetAgent=target.targetAgent();const targetRouter=target.router();const sessionId=(await targetAgent.attachToTarget(targetId,true));const connection=new ParallelConnection(targetRouter.connection(),sessionId);targetRouter.registerSession(target,sessionId,connection);connection.setOnDisconnect(()=>{targetAgent.detachFromTarget(sessionId);targetRouter.unregisterSession(sessionId);});return{connection,sessionId};}}