/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { rewriteURLForCustomProtocol, SnapshotRenderer } from './snapshotRenderer';
import { LRUCache } from '../lruCache';
export class SnapshotStorage {
    _frameSnapshots = new Map();
    _cache = new LRUCache(100_000_000); // 100MB per each trace
    _contextToResources = new Map();
    _resourceUrlsWithOverrides = new Set();
    addResource(contextId, resource) {
        resource.request.url = rewriteURLForCustomProtocol(resource.request.url);
        this._ensureResourcesForContext(contextId).push(resource);
    }
    addFrameSnapshot(contextId, snapshot, screencastFrames) {
        for (const override of snapshot.resourceOverrides)
            override.url = rewriteURLForCustomProtocol(override.url);
        let frameSnapshots = this._frameSnapshots.get(snapshot.frameId);
        if (!frameSnapshots) {
            frameSnapshots = {
                raw: [],
                renderers: [],
            };
            this._frameSnapshots.set(snapshot.frameId, frameSnapshots);
            if (snapshot.isMainFrame)
                this._frameSnapshots.set(snapshot.pageId, frameSnapshots);
        }
        frameSnapshots.raw.push(snapshot);
        const resources = this._ensureResourcesForContext(contextId);
        const renderer = new SnapshotRenderer(this._cache, resources, frameSnapshots.raw, screencastFrames, frameSnapshots.raw.length - 1);
        frameSnapshots.renderers.push(renderer);
        return renderer;
    }
    snapshotByName(pageOrFrameId, snapshotName) {
        const snapshot = this._frameSnapshots.get(pageOrFrameId);
        return snapshot?.renderers.find(r => r.snapshotName === snapshotName);
    }
    snapshotsForTest() {
        return [...this._frameSnapshots.keys()];
    }
    finalize() {
        // Resources are not necessarily sorted in the trace file, so sort them now.
        for (const resources of this._contextToResources.values())
            resources.sort((a, b) => (a._monotonicTime || 0) - (b._monotonicTime || 0));
        // Resources that have overrides should not be cached, otherwise we might get stale content
        // while serving snapshots with different override values.
        for (const frameSnapshots of this._frameSnapshots.values()) {
            for (const snapshot of frameSnapshots.raw) {
                for (const override of snapshot.resourceOverrides)
                    this._resourceUrlsWithOverrides.add(override.url);
            }
        }
    }
    hasResourceOverride(url) {
        return this._resourceUrlsWithOverrides.has(url);
    }
    _ensureResourcesForContext(contextId) {
        let resources = this._contextToResources.get(contextId);
        if (!resources) {
            resources = [];
            this._contextToResources.set(contextId, resources);
        }
        return resources;
    }
}
//# sourceMappingURL=snapshotStorage.js.map