"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrainingContextBase = void 0;
const TrainingContext_1 = require("./TrainingContext");
const frame_utils_1 = require("./frame-utils");
const FrameContextTracker_1 = require("./FrameContextTracker");
class TrainingContextBase {
    constructor(options) {
        this.runInMainWorld = options.runInMainWorld;
        this.executorCallbacks = options.executorCallbacks ?? {};
        this.frameContextTracker = new FrameContextTracker_1.FrameContextTracker({
            runInMainWorld: options.runInMainWorld,
            exposedMessagingFunction: options.exposedMessagingFunction,
            onInitializeFrame: options.onInitializeFrame,
        });
    }
    isCurrentFrameInActiveTab() {
        const frameId = this.frameContextTracker.getCurrentFrameId();
        const currentPageId = this.frameContextTracker.getCurrentPageId();
        if (!frameId || !currentPageId) {
            return false;
        }
        const frame = this.frameContextTracker.getFrame(frameId);
        const page = this.frameContextTracker.getPage(currentPageId);
        if (!frame || !page) {
            return false;
        }
        return frame.page().getPageId() === page.getPageId();
    }
    async sendMessageToAllFramesOfAllTabs(message, _callback) {
        try {
            const browser = await this.getBrowser();
            if (!browser) {
                console.warn('Trying to send message to frames, but no browser exists.', message);
                return;
            }
            const pages = await browser.pages();
            await this.frameContextTracker.sendMessageToAllFramesInPages(message, pages);
        }
        catch (e) {
            console.error('Error sending message to all frames:', e);
        }
    }
    async sendMessageToAllFramesOfActiveTabs(message) {
        const activePageIds = await this.frameContextTracker.getAllActivePageIds();
        const activePages = activePageIds
            .map((pageId) => this.frameContextTracker.getPage(pageId))
            .filter((page) => page !== undefined);
        await this.frameContextTracker.sendMessageToAllFramesInPages(message, activePages);
    }
    trackTrainingTab(tabId) {
        this.frameContextTracker.trackFramePage(tabId);
    }
    trackFrameInfo(frameId, frameElementInfo) {
        this.frameContextTracker.trackFrameSelectorInfo(String(frameId), frameElementInfo);
    }
    getTabSelectorInfo(tabId) {
        return this.frameContextTracker.getPageSelectorInfo(tabId);
    }
    getActiveTab() {
        return this.frameContextTracker.getCurrentPageId();
    }
    findActiveTab() {
        return this.frameContextTracker.getActivePageId();
    }
    setCurrentTab(tabId) {
        this.frameContextTracker.setCurrentPageId(tabId);
        this.executorCallbacks.onPageSwitch?.(tabId);
    }
    getCurrentTab() {
        return this.frameContextTracker.getCurrentPageId();
    }
    setCurrentFrameToRoot() {
        this.setCurrentFrame(TrainingContext_1.ROOT_FRAME);
    }
    setCurrentFrame(frameId) {
        this.frameContextTracker.setCurrentFrameId(frameId);
        if (frameId !== TrainingContext_1.ROOT_FRAME) {
            const frame = this.frameContextTracker.getFrame(frameId);
            if (frame) {
                this.executorCallbacks.onFrameSwitch?.(frame);
            }
            else {
                console.warn(`Unable to switch to frame with id ${frameId}, frame is not known to the frame tracker.`);
            }
        }
        else {
            this.executorCallbacks.onFrameSwitchToRoot?.();
        }
    }
    getCurrentFrame() {
        return this.frameContextTracker.getCurrentFrameId();
    }
    getFrameIdSelectorInfo(frameId) {
        return this.frameContextTracker.getFrameSelectorInfo(frameId);
    }
    setFrameIdBySelector(selector, frame) {
        let frameId = this.frameContextTracker.getFrameIdBySelector(selector);
        if (!frameId && frame) {
            frameId = frame.id();
            if (frameId) {
                this.frameContextTracker.performInitialFrameTracking(frameId, frame, selector);
            }
        }
        if (frameId) {
            this.setCurrentFrame(frameId);
        }
        else {
            this.setCurrentFrameToRoot();
        }
        return Promise.resolve(true);
    }
    sendMessageToRootFrameOfAllTabs(message, _callback) {
        this.frameContextTracker.sendMessageToRootFrameOfAllPages(message);
    }
    sendMessageToAllFramesOfCurrentTab(message) {
        this.frameContextTracker
            .sendMessageToAllFramesOfCurrentPage(message)
            .catch(console.error);
    }
    async sendMessageToRootFrameOfActiveTab(message, returnHandle) {
        return this.frameContextTracker.sendMessageToRootFrameInCurrentPage(message, returnHandle ?? false);
    }
    async sendMessageToActiveFrameAndTab(message, returnHandle) {
        return this.frameContextTracker.sendMessageToCurrentFrame(message, returnHandle ?? false);
    }
    sendMessageToRootFrame(_tabId, message) {
        const pageId = this.frameContextTracker.getCurrentPageId();
        this.frameContextTracker
            .sendMessageToPageRoot(pageId, message)
            .catch(console.error);
    }
    async sendMessageToTabAndFrame(message, tabId, frameId, returnHandle) {
        if ((0, frame_utils_1.isRootFrameId)(frameId)) {
            return this.frameContextTracker.sendMessageToPageRoot(tabId, message, returnHandle ?? false);
        }
        return this.frameContextTracker.sendMessageToFrameById(frameId, message, returnHandle ?? false);
    }
    getParentFramesForFrameId(_tabId, frameId) {
        const parentFrames = this.frameContextTracker.findPathToRootFromFrameId(String(frameId));
        parentFrames.shift();
        parentFrames.pop();
        return parentFrames.map((id) => ((0, frame_utils_1.isRootFrameId)(id) ? TrainingContext_1.ROOT_FRAME : id));
    }
    getTrackedTabsInfo() {
        const trackedPages = this.frameContextTracker.trackedPages;
        const tabsInfo = Object.keys(trackedPages)
            .map((pageId) => {
            const trackedPage = trackedPages[pageId];
            if (!trackedPage?.frame) {
                return undefined;
            }
            const page = trackedPage.frame.page();
            if (!page || page.isClosed()) {
                return undefined;
            }
            try {
                return {
                    tab_id: pageId.toString(),
                    url: page.url(),
                    title: trackedPage.selectorInfo?.title,
                };
            }
            catch (error) {
                console.debug(`Error getting tab info for page ${pageId}: ${error}`);
                return undefined;
            }
        })
            .filter((tab) => tab !== undefined);
        return Promise.resolve(tabsInfo);
    }
}
exports.TrainingContextBase = TrainingContextBase;
