// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { assert } from 'chai';
import sinon from 'sinon';
import { assertScreenshot, renderElementIntoDOM } from '../../testing/DOMHelpers.js';
import { createTarget } from '../../testing/EnvironmentHelpers.js';
import { describeWithMockConnection } from '../../testing/MockConnection.js';
import { createViewFunctionStub } from '../../testing/ViewFunctionHelpers.js';
import * as UI from '../../ui/legacy/legacy.js';
import * as WebAudio from './web_audio.js';
const context1 = {
    contextId: '924c4ee4-4cae-4e62-b4c6-71603edc39fd',
    contextType: "realtime" /* Protocol.WebAudio.ContextType.Realtime */,
    contextState: "running" /* Protocol.WebAudio.ContextState.Running */,
    sampleRate: 44100,
    callbackBufferSize: 1024,
    maxOutputChannelCount: 2,
};
const context2 = {
    contextId: '78a3e94e-4968-4bf6-8905-325109695c9e',
    contextType: "realtime" /* Protocol.WebAudio.ContextType.Realtime */,
    contextState: "running" /* Protocol.WebAudio.ContextState.Running */,
    sampleRate: 44100,
    callbackBufferSize: 1024,
    maxOutputChannelCount: 2,
};
describeWithMockConnection('WebAudioView', () => {
    beforeEach(() => {
        UI.ActionRegistration.registerActionExtension({
            actionId: 'components.collect-garbage',
            category: "PERFORMANCE" /* UI.ActionRegistration.ActionCategory.PERFORMANCE */,
            title: () => 'mock',
            toggleable: true,
        });
        sinon.stub(UI.ShortcutRegistry.ShortcutRegistry, 'instance').returns({
            shortcutTitleForAction: () => { },
            shortcutsForAction: () => [],
        });
    });
    afterEach(() => {
        UI.ActionRegistration.reset();
    });
    it('shows placeholder', async () => {
        const viewFunction = WebAudio.WebAudioView.DEFAULT_VIEW;
        const container = document.createElement('div');
        renderElementIntoDOM(container, { includeCommonStyles: true });
        viewFunction({
            contexts: [],
            selectedContextIndex: -1,
            onContextSelectorSelectionChanged: () => { },
            contextRealtimeData: null
        }, {}, container);
        await assertScreenshot('web_audio/web-audio-view-placeholder.png');
        container.remove();
    });
    it('shows contexts', async () => {
        const viewFunction = WebAudio.WebAudioView.DEFAULT_VIEW;
        const container = document.createElement('div');
        renderElementIntoDOM(container, { includeCommonStyles: true });
        viewFunction({
            contexts: [context1, context2],
            selectedContextIndex: 0,
            onContextSelectorSelectionChanged: () => { },
            contextRealtimeData: null
        }, {}, container);
        await assertScreenshot('web_audio/web-audio-view-contexts.png');
        container.remove();
    });
    it('starts empty', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view), { includeCommonStyles: true });
        assert.isEmpty(view.input.contexts);
        assert.strictEqual(view.input.selectedContextIndex, -1);
    });
    it('selects created context', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context1]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('clears list on reset', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ModelReset" /* WebAudio.WebAudioModel.Events.MODEL_RESET */);
        const input = await view.nextInput;
        assert.isEmpty(input.contexts);
        assert.strictEqual(input.selectedContextIndex, -1);
    });
    it('re-selects created context after change', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextChanged" /* WebAudio.WebAudioModel.Events.CONTEXT_CHANGED */, context1);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context1]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('keeps first context selected when another is added', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context2);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context1, context2]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('does not change selection when a different context is changed', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context2);
        await view.nextInput;
        model.dispatchEventToListeners("ContextChanged" /* WebAudio.WebAudioModel.Events.CONTEXT_CHANGED */, context2);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context1, context2]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('selects the context that was chosen', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context2);
        await view.nextInput;
        assert.exists(view.input);
        view.input.onContextSelectorSelectionChanged(context2.contextId);
        const input = await view.nextInput;
        assert.strictEqual(input.selectedContextIndex, 1);
    });
    it('keeps context selected when another is destroyed', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context2);
        await view.nextInput;
        model.dispatchEventToListeners("ContextDestroyed" /* WebAudio.WebAudioModel.Events.CONTEXT_DESTROYED */, context2.contextId);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context1]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('selects another context when the selected one is destroyed', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context2);
        await view.nextInput;
        model.dispatchEventToListeners("ContextDestroyed" /* WebAudio.WebAudioModel.Events.CONTEXT_DESTROYED */, context1.contextId);
        const input = await view.nextInput;
        assert.deepEqual(input.contexts, [context2]);
        assert.strictEqual(input.selectedContextIndex, 0);
    });
    it('selects nothing when the only context is destroyed', async () => {
        const view = createViewFunctionStub(WebAudio.WebAudioView.WebAudioView);
        renderElementIntoDOM(new WebAudio.WebAudioView.WebAudioView(undefined, view));
        const target = createTarget();
        const model = target.model(WebAudio.WebAudioModel.WebAudioModel);
        assert.exists(model);
        model.dispatchEventToListeners("ContextCreated" /* WebAudio.WebAudioModel.Events.CONTEXT_CREATED */, context1);
        await view.nextInput;
        model.dispatchEventToListeners("ContextDestroyed" /* WebAudio.WebAudioModel.Events.CONTEXT_DESTROYED */, context1.contextId);
        const input = await view.nextInput;
        assert.isEmpty(input.contexts);
        assert.strictEqual(input.selectedContextIndex, -1);
    });
});
//# sourceMappingURL=WebAudioView.test.js.map