import { InspectorContext } from "./context.mjs";
import * as impl from "./methods.mjs";
import { getParsedEvent } from "./internal-utils.mjs";
import { Agent } from '#self';
const ignoreNamespaces = ['Network'];
const ignoreMethods = [];
export { createConsole } from "./utils.mjs";
export class Inspector {
    #context = new InspectorContext(this);
    #agents = [];
    attachAgent(agent, priorRealms) {
        const oldOnDebugger = agent.hostDefinedOptions.onDebugger;
        agent.hostDefinedOptions.onDebugger = () => {
            oldOnDebugger?.();
            this.sendEvent['Debugger.paused']({
                reason: 'debugCommand',
                callFrames: this.#context.getDebuggerCallFrame(),
            });
        };
        const oldOnRealmCreated = agent.hostDefinedOptions.onRealmCreated;
        agent.hostDefinedOptions.onRealmCreated = (realm) => {
            oldOnRealmCreated?.(realm);
            this.#context.attachRealm(realm, agent);
        };
        const oldOnScriptParsed = agent.hostDefinedOptions.onScriptParsed;
        agent.hostDefinedOptions.onScriptParsed = (script, id) => {
            oldOnScriptParsed?.(script, id);
            const realmId = this.#context.getRealm(script.Realm)?.descriptor.id;
            if (realmId === undefined) {
                return;
            }
            this.sendEvent['Debugger.scriptParsed'](getParsedEvent(script, id, realmId));
        };
        this.#agents.push({
            agent,
            onDetach: () => {
                agent.hostDefinedOptions.onDebugger = oldOnDebugger;
                agent.hostDefinedOptions.onRealmCreated = oldOnRealmCreated;
                agent.hostDefinedOptions.onScriptParsed = oldOnScriptParsed;
                this.#agents = this.#agents.filter((x) => x.agent !== agent);
            },
        });
        priorRealms.forEach((realm) => {
            this.#context.attachRealm(realm, agent);
        });
    }
    detachAgent(agent) {
        const record = this.#agents.find((x) => x.agent === agent);
        record?.onDetach();
        this.#context.detachAgent(agent);
    }
    preference = { previewDebug: false };
    onMessage(id, methodArg, params) {
        if (ignoreMethods.includes(methodArg)) {
            return;
        }
        const [namespace, method] = methodArg.split('.');
        if (ignoreNamespaces.includes(namespace)) {
            return;
        }
        if (!(namespace in impl)) {
            // eslint-disable-next-line no-console
            console.error(`Unknown namespace requested: ${namespace}`);
            return;
        }
        const ns = impl[namespace];
        if (!(method in ns)) {
            // eslint-disable-next-line no-console
            console.error(`Unknown method requested: ${namespace}.${method}`);
            return;
        }
        const f = ns[method];
        new Promise((resolve) => {
            resolve(f(params, this.#debugContext));
        }).then((result = {}) => {
            this.send({ id, result });
        });
    }
    sendEvent = Object.create(new Proxy({}, {
        get: (_, key) => {
            const f = (params) => {
                this.send({ method: key, params });
            };
            Object.defineProperty(this.sendEvent, key, { value: f });
            return f;
        },
    }));
    console(realm, type, args) {
        const context = this.#context.getRealm(realm);
        if (!context) {
            return;
        }
        this.sendEvent['Runtime.consoleAPICalled']({
            type,
            args: args.map((x) => this.#context.toRemoteObject(x, {})),
            executionContextId: context.descriptor.id,
            timestamp: Date.now(),
        });
    }
    #debugContext = {
        sendEvent: this.sendEvent,
        preference: this.preference,
        context: this.#context,
        onDebuggerAttached: () => {
            this.#context.realms.forEach((realm) => {
                if (realm) {
                    this.sendEvent['Runtime.executionContextCreated']({
                        context: realm.descriptor,
                    });
                }
            });
        },
    };
}
//# sourceMappingURL=index.mjs.map