import*as Common from"../common/common.js";import*as SDK from"../sdk/sdk.js";import*as TimelineModel from"../timeline_model/timeline_model.js";import{TimelineUIUtils}from"./TimelineUIUtils.js";export class PerformanceModel extends Common.ObjectWrapper.ObjectWrapper{constructor(){super(),this._mainTarget=null,this._tracingModel=null,this._filters=[],this._timelineModel=new TimelineModel.TimelineModel.TimelineModelImpl,this._frameModel=new TimelineModel.TimelineFrameModel.TimelineFrameModel((e=>TimelineUIUtils.eventStyle(e).category.name)),this._filmStripModel=null,this._irModel=new TimelineModel.TimelineIRModel.TimelineIRModel,this._window={left:0,right:1/0},this._extensionTracingModels=[],this._recordStartTime=void 0}setMainTarget(e){this._mainTarget=e}mainTarget(){return this._mainTarget}setRecordStartTime(e){this._recordStartTime=e}recordStartTime(){return this._recordStartTime}setFilters(e){this._filters=e}filters(){return this._filters}isVisible(e){return this._filters.every((i=>i.accept(e)))}setTracingModel(e){this._tracingModel=e,this._timelineModel.setEvents(e);let i=null,t=null;for(const r of this._timelineModel.tracks())r.type===TimelineModel.TimelineModel.TrackType.Input&&(i=r.asyncEvents),r.type===TimelineModel.TimelineModel.TrackType.Animation&&(t=r.asyncEvents);(i||t)&&this._irModel.populate(i||[],t||[]);const n=this._timelineModel.tracks().filter((e=>e.type===TimelineModel.TimelineModel.TrackType.MainThread&&e.forMainFrame&&e.events.length)).map((e=>{const i=e.events[0];return{thread:i.thread,time:i.startTime}}));this._frameModel.addTraceEvents(this._mainTarget,this._timelineModel.inspectedTargetEvents(),n);for(const r of this._extensionTracingModels)r.model.adjustTime(this._tracingModel.minimumRecordTime()+r.timeOffset/1e3-this._recordStartTime);this._autoWindowTimes()}addExtensionEvents(e,i,t){this._extensionTracingModels.push({model:i,title:e,timeOffset:t}),this._tracingModel&&(i.adjustTime(this._tracingModel.minimumRecordTime()+t/1e3-this._recordStartTime),this.dispatchEventToListeners(Events.ExtensionDataAdded))}tracingModel(){if(!this._tracingModel)throw"call setTracingModel before accessing PerformanceModel";return this._tracingModel}timelineModel(){return this._timelineModel}filmStripModel(){if(this._filmStripModel)return this._filmStripModel;if(!this._tracingModel)throw"call setTracingModel before accessing PerformanceModel";return this._filmStripModel=new SDK.FilmStripModel.FilmStripModel(this._tracingModel),this._filmStripModel}frames(){return this._frameModel.frames()}frameModel(){return this._frameModel}interactionRecords(){return this._irModel.interactionRecords()}extensionInfo(){return this._extensionTracingModels}dispose(){this._tracingModel&&this._tracingModel.dispose();for(const e of this._extensionTracingModels)e.model.dispose()}filmStripModelFrame(e){const i=e.idle?e.startTime:e.endTime,t=this._filmStripModel.frameByTimestamp(i);return t&&t.timestamp-e.endTime<10?t:null}save(e){if(!this._tracingModel)throw"call setTracingModel before accessing PerformanceModel";return this._tracingModel.backingStorage().writeToStream(e)}setWindow(e,i){this._window=e,this.dispatchEventToListeners(Events.WindowChanged,{window:e,animate:i})}window(){return this._window}_autoWindowTimes(){const e=this._timelineModel;let i=[];for(const m of e.tracks())m.type===TimelineModel.TimelineModel.TrackType.MainThread&&m.forMainFrame&&(i=m.tasks);if(!i.length)return void this.setWindow({left:e.minimumRecordTime(),right:e.maximumRecordTime()});function t(e,t){let n=e,r=(i[n].startTime+i[n].endTime)/2,o=0;const s=Math.sign(t-e);for(let l=e;l!==t;l+=s){const e=i[l],t=(e.startTime+e.endTime)/2;o<.1*Math.abs(r-t)&&(n=l,r=t,o=0),o+=e.duration}return n}const n=t(i.length-1,0),r=t(0,n);let o=i[r].startTime,s=i[n].endTime;const l=s-o;l<.1*(e.maximumRecordTime()-e.minimumRecordTime())?(o=e.minimumRecordTime(),s=e.maximumRecordTime()):(o=Math.max(o-.05*l,e.minimumRecordTime()),s=Math.min(s+.05*l,e.maximumRecordTime())),this.setWindow({left:o,right:s})}}export const Events={ExtensionDataAdded:Symbol("ExtensionDataAdded"),WindowChanged:Symbol("WindowChanged")};export let Window;