export class TestOpenCodeRuntime {
    constructor() {
        this.acquisitions = [];
        this.clientCreations = [];
        this.clients = [];
        this.server = { port: 1234, url: "http://127.0.0.1:1234" };
    }
    enqueueClient(client) {
        this.clients.push(client);
    }
    async acquireServer(options) {
        const acquisition = { force: options.force, env: options.env, releaseCount: 0 };
        this.acquisitions.push(acquisition);
        return {
            server: this.server,
            release: () => {
                acquisition.releaseCount += 1;
            },
        };
    }
    async ensureServerRunning() {
        return this.server;
    }
    createClient(options) {
        this.clientCreations.push(options);
        const client = this.clients.shift() ?? new TestOpenCodeClient();
        return client.asSdkClient();
    }
    async shutdown() { }
}
export class TestOpenCodeClient {
    constructor() {
        this.calls = {
            appAgents: [],
            commandList: [],
            eventSubscribe: [],
            experimentalSessionList: [],
            globalEvent: [],
            mcpAdd: [],
            mcpConnect: [],
            permissionReply: [],
            providerList: [],
            questionReject: [],
            questionReply: [],
            sessionAbort: [],
            sessionCommand: [],
            sessionCreate: [],
            sessionDelete: [],
            sessionMessages: [],
            sessionPromptAsync: [],
            sessionSummarize: [],
            sessionUpdate: [],
        };
        this.appAgentsResponse = { data: [] };
        this.commandListResponse = { data: [] };
        this.experimentalSessionListResponse = { data: [] };
        this.mcpAddResponse = {};
        this.mcpConnectResponse = {};
        this.permissionReplyResponse = {};
        this.providerListResponse = { data: { connected: [], all: [] } };
        this.providerListImplementation = null;
        this.questionRejectResponse = {};
        this.questionReplyResponse = {};
        this.sessionAbortResponse = {};
        this.sessionCommandError = null;
        this.sessionCommandEvents = [idleEvent()];
        this.sessionCommandResponse = {};
        this.sessionCreateResponse = { data: { id: "session-1" } };
        this.sessionDeleteResponse = {};
        this.sessionMessagesResponse = { data: [] };
        this.sessionPromptAsyncEvents = [idleEvent()];
        this.sessionPromptAsyncResponse = {};
        this.sessionSummarizeResponse = { data: {} };
        this.sessionUpdateResponse = {};
        this.queuedEventStream = createQueuedEventStream();
        this.eventStream = this.queuedEventStream.stream;
    }
    emitEvent(event) {
        this.queuedEventStream.emit(event);
    }
    asSdkClient() {
        return {
            app: {
                agents: async (parameters) => {
                    this.calls.appAgents.push(parameters);
                    return this.appAgentsResponse;
                },
            },
            command: {
                list: async (parameters) => {
                    this.calls.commandList.push(parameters);
                    return this.commandListResponse;
                },
            },
            event: {
                subscribe: async (parameters, options) => {
                    this.calls.eventSubscribe.push({ parameters, options });
                    return { stream: this.eventStream };
                },
            },
            experimental: {
                session: {
                    list: async (parameters) => {
                        this.calls.experimentalSessionList.push(parameters);
                        return this.experimentalSessionListResponse;
                    },
                },
            },
            global: {
                event: async (options) => {
                    this.calls.globalEvent.push(options);
                    return { stream: this.eventStream };
                },
            },
            mcp: {
                add: async (parameters) => {
                    this.calls.mcpAdd.push(parameters);
                    return this.mcpAddResponse;
                },
                connect: async (parameters) => {
                    this.calls.mcpConnect.push(parameters);
                    return this.mcpConnectResponse;
                },
            },
            permission: {
                reply: async (parameters) => {
                    this.calls.permissionReply.push(parameters);
                    return this.permissionReplyResponse;
                },
            },
            provider: {
                list: async (parameters) => {
                    this.calls.providerList.push(parameters);
                    return this.providerListImplementation
                        ? await this.providerListImplementation()
                        : this.providerListResponse;
                },
            },
            question: {
                reject: async (parameters) => {
                    this.calls.questionReject.push(parameters);
                    return this.questionRejectResponse;
                },
                reply: async (parameters) => {
                    this.calls.questionReply.push(parameters);
                    return this.questionReplyResponse;
                },
            },
            session: {
                abort: async (parameters) => {
                    this.calls.sessionAbort.push(parameters);
                    return this.sessionAbortResponse;
                },
                command: async (parameters) => {
                    this.calls.sessionCommand.push(parameters);
                    if (this.sessionCommandError) {
                        throw this.sessionCommandError;
                    }
                    for (const event of this.sessionCommandEvents) {
                        this.emitEvent(event);
                    }
                    return this.sessionCommandResponse;
                },
                create: async (parameters) => {
                    this.calls.sessionCreate.push(parameters);
                    return this.sessionCreateResponse;
                },
                delete: async (parameters) => {
                    this.calls.sessionDelete.push(parameters);
                    return this.sessionDeleteResponse;
                },
                messages: async (parameters) => {
                    this.calls.sessionMessages.push(parameters);
                    return this.sessionMessagesResponse;
                },
                promptAsync: async (parameters) => {
                    this.calls.sessionPromptAsync.push(parameters);
                    for (const event of this.sessionPromptAsyncEvents) {
                        this.emitEvent(event);
                    }
                    return this.sessionPromptAsyncResponse;
                },
                summarize: async (parameters) => {
                    this.calls.sessionSummarize.push(parameters);
                    return this.sessionSummarizeResponse;
                },
                update: async (parameters) => {
                    this.calls.sessionUpdate.push(parameters);
                    return this.sessionUpdateResponse;
                },
            },
        };
    }
}
export function createEventStream(events) {
    return (async function* () {
        for (const event of events) {
            yield event;
        }
    })();
}
function createQueuedEventStream() {
    const queue = [];
    const waiters = [];
    return {
        stream: {
            [Symbol.asyncIterator]: () => ({
                next: () => {
                    const event = queue.shift();
                    if (event !== undefined) {
                        return Promise.resolve({ done: false, value: event });
                    }
                    return new Promise((resolve) => {
                        waiters.push(resolve);
                    });
                },
            }),
        },
        emit: (event) => {
            const waiter = waiters.shift();
            if (waiter) {
                waiter({ done: false, value: event });
                return;
            }
            queue.push(event);
        },
    };
}
export function idleEvent() {
    return {
        type: "session.idle",
        properties: { sessionID: "session-1" },
    };
}
//# sourceMappingURL=test-opencode-runtime.js.map