"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlaywrightService = void 0;
const inversify_1 = require("inversify");
const playwright_1 = require("playwright");
const config_js_1 = require("../../config.js");
const logger_js_1 = require("../../logger.js");
const browser_js_1 = require("./browser.js");
let PlaywrightService = class PlaywrightService {
    constructor(logger, config) {
        this.logger = logger;
        this.config = config;
        this.cachedPages = new Map();
        this.endpointUrl = `http://${this.config.get(browser_js_1.CHROME_ADDRESS)}:${this.config.get(browser_js_1.CHROME_PORT)}`;
    }
    async connectOverCDP(options) {
        if (this.browser) {
            await this.browser.close();
        }
        this.browser = await playwright_1.chromium.connectOverCDP(this.endpointUrl, options);
        this.browser.on('disconnected', async () => {
            await this.disconnect();
        });
        if (this.browser.contexts().length > 0) {
            this.context = this.browser.contexts()[0];
            this.context.on('page', async (page) => {
                const pageTargetId = await this.getPageTargetId(page);
                if (pageTargetId) {
                    this.cachedPages.set(pageTargetId, page);
                    page.on('close', async (page) => {
                        for (const [key, value] of this.cachedPages) {
                            if (value === page) {
                                this.cachedPages.delete(key);
                            }
                        }
                    });
                }
            });
            await this.fillCacheForAllPages(this.context.pages());
            if (!this.targetId) {
                this.currentPage = this.context.pages()[0];
            }
            else {
                this.currentPage = this.cachedPages.get(this.targetId);
            }
        }
    }
    async disconnect() {
        await this.browser?.close();
        this.browser = undefined;
        this.context = undefined;
        this.currentPage = undefined;
        this.targetId = undefined;
        this.cachedPages.clear();
    }
    async fillCacheForAllPages(pages) {
        for (const page of pages) {
            const pageTargetId = await this.getPageTargetId(page);
            if (pageTargetId) {
                this.cachedPages.set(pageTargetId, page);
            }
        }
    }
    async setCurrentPage(targetId) {
        this.currentPage = undefined;
        this.targetId = targetId;
        if (!this.browser) {
            await this.connectOverCDP();
            if (!this.context) {
                this.logger.warn(`Browser not running, failed to attach to ${targetId}`);
                return;
            }
        }
        if (this.cachedPages.has(targetId)) {
            this.currentPage = this.cachedPages.get(targetId);
            return;
        }
        const reversedPages = this.context.pages().slice().reverse();
        for (const page of reversedPages) {
            const pageTargetId = await this.getPageTargetId(page);
            if (pageTargetId === targetId) {
                this.currentPage = page;
                return;
            }
        }
        this.logger.warn(`Failed to set current Playwright Page to ${targetId}`);
    }
    async getPageTargetId(page) {
        let targetId = null;
        try {
            const session = await page.context().newCDPSession(page);
            const { targetInfo } = await session.send('Target.getTargetInfo');
            await session.detach();
            targetId = targetInfo.targetId;
        }
        catch (error) {
            this.logger.warn(`Failed to get page target ID`, error);
        }
        return targetId;
    }
    getCurrentPage() {
        return this.currentPage;
    }
};
PlaywrightService = __decorate([
    (0, inversify_1.injectable)(),
    __param(0, (0, inversify_1.inject)(logger_js_1.Logger)),
    __param(1, (0, inversify_1.inject)(config_js_1.Configuration)),
    __metadata("design:paramtypes", [logger_js_1.Logger,
        config_js_1.Configuration])
], PlaywrightService);
exports.PlaywrightService = PlaywrightService;
//# sourceMappingURL=playwright.js.map