"use strict";
/**
 * 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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.InMemorySnapshotter = void 0;
const events_1 = require("events");
const httpServer_1 = require("../../utils/httpServer");
const helper_1 = require("../helper");
const snapshotRenderer_1 = require("./snapshotRenderer");
const snapshotServer_1 = require("./snapshotServer");
const snapshotter_1 = require("./snapshotter");
const kSnapshotInterval = 25;
class InMemorySnapshotter extends events_1.EventEmitter {
    constructor(context) {
        super();
        this._blobs = new Map();
        this._resources = new Map();
        this._frameSnapshots = new Map();
        this._snapshots = new Map();
        this._contextResources = new Map();
        this._server = new httpServer_1.HttpServer();
        new snapshotServer_1.SnapshotServer(this._server, this);
        this._snapshotter = new snapshotter_1.Snapshotter(context, this);
    }
    async initialize() {
        await this._snapshotter.initialize();
        return await this._server.start();
    }
    async start() {
        await this._snapshotter.setAutoSnapshotInterval(kSnapshotInterval);
    }
    async dispose() {
        this._snapshotter.dispose();
        await this._server.stop();
    }
    async captureSnapshot(page, snapshotId) {
        if (this._snapshots.has(snapshotId))
            throw new Error('Duplicate snapshotId: ' + snapshotId);
        this._snapshotter.captureSnapshot(page, snapshotId);
        return new Promise(fulfill => {
            const listener = helper_1.helper.addEventListener(this, 'snapshot', (renderer) => {
                if (renderer.snapshotId === snapshotId) {
                    helper_1.helper.removeEventListeners([listener]);
                    fulfill(renderer);
                }
            });
        });
    }
    async setAutoSnapshotInterval(interval) {
        await this._snapshotter.setAutoSnapshotInterval(interval);
    }
    onBlob(blob) {
        this._blobs.set(blob.sha1, blob.buffer);
    }
    onResource(resource) {
        this._resources.set(resource.resourceId, resource);
        let resources = this._contextResources.get(resource.url);
        if (!resources) {
            resources = [];
            this._contextResources.set(resource.url, resources);
        }
        resources.push({ frameId: resource.frameId, resourceId: resource.resourceId });
    }
    onFrameSnapshot(snapshot) {
        let frameSnapshots = this._frameSnapshots.get(snapshot.frameId);
        if (!frameSnapshots) {
            frameSnapshots = [];
            this._frameSnapshots.set(snapshot.frameId, frameSnapshots);
        }
        frameSnapshots.push(snapshot);
        const renderer = new snapshotRenderer_1.SnapshotRenderer(new Map(this._contextResources), frameSnapshots, frameSnapshots.length - 1);
        this._snapshots.set(snapshot.snapshotId, renderer);
        this.emit('snapshot', renderer);
    }
    resourceContent(sha1) {
        return this._blobs.get(sha1);
    }
    resourceById(resourceId) {
        return this._resources.get(resourceId);
    }
    snapshotById(snapshotId) {
        return this._snapshots.get(snapshotId);
    }
    frameSnapshots(frameId) {
        return this._frameSnapshots.get(frameId) || [];
    }
}
exports.InMemorySnapshotter = InMemorySnapshotter;
//# sourceMappingURL=inMemorySnapshotter.js.map