import*as Common from"../common/common.js";import{RuntimeModel}from"./RuntimeModel.js";import{TargetManager}from"./SDKModel.js";let isolateManagerInstance;export class IsolateManager extends Common.ObjectWrapper.ObjectWrapper{constructor(){super(),this._isolates=new Map,this._isolateIdByModel=new Map,this._observers=new Set,TargetManager.instance().observeModels(RuntimeModel,this),this._pollId=0}static instance({forceNew:e}={forceNew:!1}){return isolateManagerInstance&&!e||(isolateManagerInstance=new IsolateManager),isolateManagerInstance}observeIsolates(e){if(this._observers.has(e))throw new Error("Observer can only be registered once");this._observers.size||this._poll(),this._observers.add(e);for(const s of this._isolates.values())e.isolateAdded(s)}unobserveIsolates(e){this._observers.delete(e),this._observers.size||++this._pollId}modelAdded(e){this._modelAdded(e)}async _modelAdded(e){this._isolateIdByModel.set(e,null);const s=await e.isolateId();if(!this._isolateIdByModel.has(e))return;if(!s)return void this._isolateIdByModel.delete(e);this._isolateIdByModel.set(e,s);let t=this._isolates.get(s);if(t||(t=new Isolate(s),this._isolates.set(s,t)),t._models.add(e),1===t._models.size)for(const i of this._observers)i.isolateAdded(t);else for(const i of this._observers)i.isolateChanged(t)}modelRemoved(e){const s=this._isolateIdByModel.get(e);if(this._isolateIdByModel.delete(e),!s)return;const t=this._isolates.get(s);if(t)if(t._models.delete(e),t._models.size)for(const i of this._observers)i.isolateChanged(t);else{for(const e of this._observers)e.isolateRemoved(t);this._isolates.delete(s)}}isolateByModel(e){return this._isolates.get(this._isolateIdByModel.get(e)||"")||null}isolates(){return this._isolates.values()}async _poll(){const e=this._pollId;for(;e===this._pollId;)await Promise.all(Array.from(this.isolates(),(e=>e._update()))),await new Promise((e=>setTimeout(e,PollIntervalMs)))}}export class Observer{isolateAdded(e){}isolateRemoved(e){}isolateChanged(e){}}export const Events={MemoryChanged:Symbol("MemoryChanged")};export const MemoryTrendWindowMs=12e4;const PollIntervalMs=2e3;export class Isolate{constructor(e){this._id=e,this._models=new Set,this._usedHeapSize=0;const s=12e4/PollIntervalMs;this._memoryTrend=new MemoryTrend(s)}id(){return this._id}models(){return this._models}runtimeModel(){return this._models.values().next().value||null}heapProfilerModel(){const e=this.runtimeModel();return e&&e.heapProfilerModel()}async _update(){const e=this.runtimeModel(),s=e&&await e.heapUsage();s&&(this._usedHeapSize=s.usedSize,this._memoryTrend.add(this._usedHeapSize),IsolateManager.instance().dispatchEventToListeners(Events.MemoryChanged,this))}samplesCount(){return this._memoryTrend.count()}usedHeapSize(){return this._usedHeapSize}usedHeapSizeGrowRate(){return this._memoryTrend.fitSlope()}isMainThread(){const e=this.runtimeModel();return!!e&&"main"===e.target().id()}}export class MemoryTrend{constructor(e){this._maxCount=0|e,this._base,this._index,this._x,this._y,this._sx,this._sy,this._sxx,this._sxy,this.reset()}reset(){this._base=Date.now(),this._index=0,this._x=[],this._y=[],this._sx=0,this._sy=0,this._sxx=0,this._sxy=0}count(){return this._x.length}add(e,s){const t="number"===typeof s?s:Date.now()-this._base,i=e;if(this._x.length===this._maxCount){const e=this._x[this._index],s=this._y[this._index];this._sx-=e,this._sy-=s,this._sxx-=e*e,this._sxy-=e*s}this._sx+=t,this._sy+=i,this._sxx+=t*t,this._sxy+=t*i,this._x[this._index]=t,this._y[this._index]=i,this._index=(this._index+1)%this._maxCount}fitSlope(){const e=this.count();return e<2?0:(this._sxy-this._sx*this._sy/e)/(this._sxx-this._sx*this._sx/e)}}