// Copyright 2022 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 * as Common from '../../core/common/common.js';
import * as Platform from '../../core/platform/platform.js';
import * as SDK from '../../core/sdk/sdk.js';
import * as Protocol from '../../generated/protocol.js';
import * as AiAssistance from '../../models/ai_assistance/ai_assistance.js';
import {getContextMenuForElement} from '../../testing/ContextMenuHelpers.js';
import {
  createTarget,
  describeWithEnvironment,
  expectConsoleLogs,
  updateHostConfig,
} from '../../testing/EnvironmentHelpers.js';
import {setupLocaleHooks} from '../../testing/LocaleHelpers.js';
import {MockCDPConnection} from '../../testing/MockCDPConnection.js';
import {createResource, getMainFrame, mockResourceTree} from '../../testing/ResourceTreeHelpers.js';
import {TestUniverse} from '../../testing/TestUniverse.js';
import * as UI from '../../ui/legacy/legacy.js';

import * as Application from './application.js';

const {urlString} = Platform.DevToolsPath;

describeWithEnvironment('ApplicationPanelSidebar', () => {
  let target: SDK.Target.Target;
  let tabTarget: SDK.Target.Target;

  const TEST_EXTENSION_NAME = 'Test Extension';

  beforeEach(() => {
    SDK.ChildTargetManager.ChildTargetManager.install();
    const connection = new MockCDPConnection();
    mockResourceTree(connection);
    tabTarget = createTarget({type: SDK.Target.Type.TAB, connection});
    createTarget({parentTarget: tabTarget, subtype: 'prerender'});
    target = createTarget({parentTarget: tabTarget});
    SDK.TargetManager.TargetManager.instance().setScopeTarget(target);
    sinon.stub(UI.ViewManager.ViewManager.instance(), 'showView').resolves();  // Silence console error
  });

  it('shows WebMCP tree element', async () => {
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    assert.exists(sidebar.webMcpTreeElement);
  });

  it('shows Ads panel only if the Ads panel config is enabled', async () => {
    updateHostConfig({devToolsAdsPanel: {enabled: true}});
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    let sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    assert.exists(sidebar.adsTreeElement);

    updateHostConfig({devToolsAdsPanel: {enabled: false}});
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    assert.isUndefined(sidebar.adsTreeElement);
  });

  it('shows cookies for all frames', async () => {
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
    assert.exists(resourceTreeModel);
    sinon.stub(resourceTreeModel, 'frames').returns([
      {
        url: 'https://example.com/',
        unreachableUrl: () => null,
        resourceTreeModel: () => resourceTreeModel,
      } as unknown as SDK.ResourceTreeModel.ResourceTreeFrame,
      {
        url: 'https://example.com/admin/',
        unreachableUrl: () => null,
        resourceTreeModel: () => resourceTreeModel,
      } as unknown as SDK.ResourceTreeModel.ResourceTreeFrame,
      {
        url: 'https://example.org/',
        unreachableUrl: () => null,
        resourceTreeModel: () => resourceTreeModel,
      } as unknown as SDK.ResourceTreeModel.ResourceTreeFrame,
    ]);
    resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, resourceTreeModel);

    assert.strictEqual(sidebar.cookieListTreeElement.childCount(), 2);
    assert.deepEqual(
        sidebar.cookieListTreeElement.children().map(e => e.title), ['https://example.com', 'https://example.org']);
  });

  it('shows extension storage based on added models', async () => {
    for (const useTreeView of [false, true]) {
      Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
      const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();

      // Cast to any allows overriding private method.
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      sinon.stub(sidebar, 'useTreeViewForExtensionStorage' as any).returns(useTreeView);

      const extensionStorageModel = target.model(Application.ExtensionStorageModel.ExtensionStorageModel);
      assert.exists(extensionStorageModel);

      const makeFakeExtensionStorage = (storageArea: Protocol.Extensions.StorageArea) =>
          new Application.ExtensionStorageModel.ExtensionStorage(
              extensionStorageModel, '', TEST_EXTENSION_NAME, storageArea);

      const fakeModelLocal = makeFakeExtensionStorage(Protocol.Extensions.StorageArea.Local);
      const fakeModelSession = makeFakeExtensionStorage(Protocol.Extensions.StorageArea.Session);

      extensionStorageModel.dispatchEventToListeners(
          Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_ADDED, fakeModelLocal);
      extensionStorageModel.dispatchEventToListeners(
          Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_ADDED, fakeModelSession);

      if (useTreeView) {
        assert.strictEqual(sidebar.extensionStorageListTreeElement.childCount(), 1);
        assert.strictEqual(sidebar.extensionStorageListTreeElement.children()[0].title, TEST_EXTENSION_NAME);
        assert.deepEqual(
            sidebar.extensionStorageListTreeElement.children()[0].children().map(e => e.title), ['Session', 'Local']);
      } else {
        assert.strictEqual(sidebar.extensionStorageListTreeElement.childCount(), 2);
        assert.deepEqual(sidebar.extensionStorageListTreeElement.children().map(e => e.title), ['Session', 'Local']);
      }

      extensionStorageModel.dispatchEventToListeners(
          Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_REMOVED, fakeModelLocal);
      extensionStorageModel.dispatchEventToListeners(
          Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_REMOVED, fakeModelSession);
      assert.strictEqual(sidebar.extensionStorageListTreeElement.childCount(), 0);
    }
  });

  it('does not add extension storage if already added by another model', async () => {
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();

    // Fakes adding an ExtensionStorage to the ExtensionStorageModel for
    // `target`. Returns a function that can be used to trigger a removal.
    const addFakeExtensionStorage = (target: SDK.Target.Target): () => void => {
      const model = target.model(Application.ExtensionStorageModel.ExtensionStorageModel);
      assert.exists(model);

      const extensionStorage = new Application.ExtensionStorageModel.ExtensionStorage(
          model, '', TEST_EXTENSION_NAME, Protocol.Extensions.StorageArea.Local);

      const stub = sinon.stub(model, 'storageForIdAndArea').returns(extensionStorage);
      model.dispatchEventToListeners(
          Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_ADDED, extensionStorage);

      return () => {
        stub.restore();
        model.dispatchEventToListeners(
            Application.ExtensionStorageModel.Events.EXTENSION_STORAGE_REMOVED, extensionStorage);
      };
    };

    // Add a fake extension storage to the main target. The UI should be updated.
    addFakeExtensionStorage(target);
    assert.strictEqual(sidebar.extensionStorageListTreeElement.children()[0].childCount(), 1);

    // Add a fake extension storage using a non-main target (e.g, an iframe).
    // Make sure we don't add a second entry to the UI.
    const removeFrameStorage =
        addFakeExtensionStorage(createTarget({type: SDK.Target.Type.FRAME, parentTarget: target}));
    assert.strictEqual(sidebar.extensionStorageListTreeElement.children()[0].childCount(), 1);

    // Removing the frame also shouldn't do anything, since the main frame
    // still exists.
    removeFrameStorage();
    assert.strictEqual(sidebar.extensionStorageListTreeElement.children()[0].childCount(), 1);
  });

  async function getExpectedCall(expectedCall: string): Promise<sinon.SinonSpy> {
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    const components = expectedCall.split('.');
    assert.lengthOf(components, 2);
    // @ts-expect-error
    const object = sidebar[components[0]];
    assert.exists(object);
    return sinon.spy(object, components[1]);
  }

  const MOCK_EVENT_ITEM = {
    addEventListener: () => {},
    securityOrigin: 'https://example.com',
    databaseId: new Application.IndexedDBModel.DatabaseId({storageKey: ''}, ''),
    getEntries: () => Promise.resolve([]),
  };

  const testUiUpdate = <Events, T extends keyof Events>(
      event: T, modelClass: new (arg1: SDK.Target.Target) => SDK.SDKModel.SDKModel<Events>, expectedCallString: string,
      inScope: boolean) => async () => {
    SDK.TargetManager.TargetManager.instance().setScopeTarget(inScope ? target : null);
    const expectedCall = await getExpectedCall(expectedCallString);
    const model = target.model(modelClass);
    assert.exists(model);
    const data = [{...MOCK_EVENT_ITEM, model}] as Common.EventTarget.EventPayloadToRestParameters<Events, T>;
    model.dispatchEventToListeners(event as Platform.TypeScriptUtilities.NoUnion<T>, ...data);
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(expectedCall.called, inScope);
  };

  it('adds DOM storage on in scope event',
     testUiUpdate(
         SDK.DOMStorageModel.Events.DOM_STORAGE_ADDED, SDK.DOMStorageModel.DOMStorageModel,
         'sessionStorageListTreeElement.appendChild', true));

  it('does not add DOM storage on out of scope event',
     testUiUpdate(
         SDK.DOMStorageModel.Events.DOM_STORAGE_ADDED, SDK.DOMStorageModel.DOMStorageModel,
         'sessionStorageListTreeElement.appendChild', false));

  it('adds indexed DB on in scope event',
     testUiUpdate(
         Application.IndexedDBModel.Events.DatabaseAdded, Application.IndexedDBModel.IndexedDBModel,
         'indexedDBListTreeElement.appendChild', true));

  it('does not add indexed DB on out of scope event',
     testUiUpdate(
         Application.IndexedDBModel.Events.DatabaseAdded, Application.IndexedDBModel.IndexedDBModel,
         'indexedDBListTreeElement.appendChild', false));

  const MOCK_GETTER_ITEM = {
    ...MOCK_EVENT_ITEM,
    ...MOCK_EVENT_ITEM.databaseId,
  };
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const testUiUpdateOnScopeChange = <T extends SDK.SDKModel.SDKModel<any>>(
      modelClass: new (arg1: SDK.Target.Target) => T, getter: keyof T, expectedCallString: string) => async () => {
    SDK.TargetManager.TargetManager.instance().setScopeTarget(null);
    const expectedCall = await getExpectedCall(expectedCallString);
    const model = target.model(modelClass);
    assert.exists(model);
    sinon.stub(model, getter).returns([MOCK_GETTER_ITEM]);
    SDK.TargetManager.TargetManager.instance().setScopeTarget(target);
    await new Promise(resolve => setTimeout(resolve, 0));
    sinon.assert.called(expectedCall);
  };

  it('adds DOM storage element after scope change',
     testUiUpdateOnScopeChange(
         SDK.DOMStorageModel.DOMStorageModel, 'storages', 'sessionStorageListTreeElement.appendChild'));

  it('adds indexed db after scope change',
     testUiUpdateOnScopeChange(
         Application.IndexedDBModel.IndexedDBModel, 'databases', 'indexedDBListTreeElement.appendChild'));

  it('uses extension name when available for tree element title', () => {
    const panel = Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const extensionName = 'Test Extension';
    assert.strictEqual(
        new Application.ApplicationPanelSidebar.ExtensionStorageTreeParentElement(panel, 'id', extensionName).title,
        extensionName);
  });

  it('uses extension id as fallback for tree element title', () => {
    const panel = Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const extensionId = 'id';
    assert.strictEqual(
        new Application.ApplicationPanelSidebar.ExtensionStorageTreeParentElement(panel, extensionId, '').title,
        extensionId);
  });

  it('fetches schemeful site and updates DeviceBoundSessionsModel when cookie is added', async () => {
    updateHostConfig({deviceBoundSessionsDebugging: {enabled: true}});
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();

    const networkAgent = target.networkAgent();
    const fetchSchemefulSiteStub = sinon.stub(networkAgent, 'invoke_fetchSchemefulSite').resolves({
      schemefulSite: 'https://device-bound-sessions.com',
      getError: () => undefined,
    });

    const model = sidebar.deviceBoundSessionsModel;
    assert.exists(model);
    const addVisibleSiteSpy = sinon.spy(model, 'addVisibleSite');

    const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
    assert.exists(resourceTreeModel);

    const frame = {
      url: 'https://example.device-bound-sessions.com/',
      unreachableUrl: () => null,
      resourceTreeModel: () => resourceTreeModel,
      target: () => target,
    } as unknown as SDK.ResourceTreeModel.ResourceTreeFrame;

    sinon.stub(resourceTreeModel, 'frames').returns([frame]);

    resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, resourceTreeModel);
    await new Promise(resolve => setTimeout(resolve, 0));

    sinon.assert.calledWith(fetchSchemefulSiteStub, {origin: 'https://example.device-bound-sessions.com'});
    sinon.assert.calledWith(addVisibleSiteSpy, 'https://device-bound-sessions.com');
  });
});

describeWithEnvironment('IDBDatabaseTreeElement', () => {
  let target: SDK.Target.Target;
  beforeEach(() => {
    const connection = new MockCDPConnection();
    mockResourceTree(connection);
    target = createTarget({connection});
    SDK.TargetManager.TargetManager.instance().setScopeTarget(target);
  });
  expectConsoleLogs({
    error: ['Error: No LanguageSelector instance exists yet.'],
  });

  it('only becomes selectable after database is updated', () => {
    const model = target.model(Application.IndexedDBModel.IndexedDBModel);
    assert.exists(model);
    const panel = Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    const databaseId = new Application.IndexedDBModel.DatabaseId({storageKey: ''}, '');
    const treeElement = new Application.ApplicationPanelSidebar.IDBDatabaseTreeElement(panel, model, databaseId);

    assert.isFalse(treeElement.selectable);
    treeElement.update(new Application.IndexedDBModel.Database(databaseId, 1), false);
    assert.isTrue(treeElement.selectable);
  });
});

describeWithEnvironment('ResourcesSection', () => {
  const tests = (inScope: boolean) => () => {
    let target: SDK.Target.Target;
    beforeEach(() => {
      SDK.FrameManager.FrameManager.instance({forceNew: true});
      const connection = new MockCDPConnection();
      mockResourceTree(connection);
      target = createTarget({connection});
    });

    expectConsoleLogs({
      error: ['Error: No LanguageSelector instance exists yet.'],
    });

    it('adds tree elements for a frame and resource', () => {
      SDK.TargetManager.TargetManager.instance().setScopeTarget(inScope ? target : null);
      const panel = Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
      const treeElement = new UI.TreeOutline.TreeElement();
      new Application.ApplicationPanelSidebar.ResourcesSection(panel, treeElement);

      const model = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
      assert.exists(model);

      assert.strictEqual(treeElement.childCount(), 0);
      const frame = getMainFrame(target);

      const url = urlString`http://example.com`;
      assert.strictEqual(treeElement.firstChild()?.childCount() ?? 0, 0);
      createResource(frame, url, 'text/html', '');
      assert.strictEqual(treeElement.firstChild()?.childCount() ?? 0, inScope ? 1 : 0);
    });

    it('picks up existing frames and resource', () => {
      SDK.TargetManager.TargetManager.instance().setScopeTarget(null);
      const panel = Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
      const treeElement = new UI.TreeOutline.TreeElement();
      new Application.ApplicationPanelSidebar.ResourcesSection(panel, treeElement);

      const url = urlString`http://example.com`;
      createResource(getMainFrame(target), url, 'text/html', '');
      assert.strictEqual(treeElement.firstChild()?.childCount() ?? 0, 0);

      assert.strictEqual(treeElement.childCount(), 0);
      SDK.TargetManager.TargetManager.instance().setScopeTarget(inScope ? target : null);
      assert.strictEqual(treeElement.childCount(), inScope ? 1 : 0);
      assert.strictEqual(treeElement.firstChild()?.childCount() ?? 0, inScope ? 1 : 0);
    });
  };

  describe('in scope', tests(true));
  describe('out of scope', tests(false));
});

describeWithEnvironment('IndexedDBTreeElement live update', () => {
  let target: SDK.Target.Target;
  let model: Application.IndexedDBModel.IndexedDBModel;
  let sidebar: Application.ApplicationPanelSidebar.ApplicationPanelSidebar;
  let indexedDBTreeElement: Application.ApplicationPanelSidebar.IndexedDBTreeElement;

  beforeEach(async () => {
    const connection = new MockCDPConnection();
    mockResourceTree(connection);
    target = createTarget({connection});
    SDK.TargetManager.TargetManager.instance().setScopeTarget(target);
    model = target.model(Application.IndexedDBModel.IndexedDBModel) as Application.IndexedDBModel.IndexedDBModel;
    sinon.stub(model, 'refreshDatabase');
    sinon.stub(UI.ViewManager.ViewManager.instance(), 'showView').resolves();  // Silence console error
    SDK.ChildTargetManager.ChildTargetManager.install();
    Application.ResourcesPanel.ResourcesPanel.instance({forceNew: true});
    sidebar = await Application.ResourcesPanel.ResourcesPanel.showAndGetSidebar();
    indexedDBTreeElement = sidebar.indexedDBListTreeElement;
  });

  it('updates tree on database, object store, and index changes', async () => {
    const MAIN_FRAME_ID = 'main' as Protocol.Page.FrameId;
    const storageKey = `test-storage-key|${MAIN_FRAME_ID}|http://www.example.com`;
    assert.strictEqual(indexedDBTreeElement.childCount(), 0);

    // 1. Create database "database1"
    const db1Id = new Application.IndexedDBModel.DatabaseId({storageKey}, 'database1');
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseAdded, {databaseId: db1Id, model});
    const db1 = new Application.IndexedDBModel.Database(db1Id, 1);
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: false});
    await new Promise(resolve => setTimeout(resolve, 0));

    assert.strictEqual(indexedDBTreeElement.childCount(), 1);
    const db1TreeElement = indexedDBTreeElement.children()[0];
    assert.strictEqual(db1TreeElement.titleAsText(), 'database1');
    assert.strictEqual(db1TreeElement.childCount(), 0);

    // 2. Create database "database2"
    const db2Id = new Application.IndexedDBModel.DatabaseId({storageKey}, 'database2');
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseAdded, {databaseId: db2Id, model});
    const db2 = new Application.IndexedDBModel.Database(db2Id, 1);
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db2, model, entriesUpdated: false});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(indexedDBTreeElement.childCount(), 2);
    assert.strictEqual(indexedDBTreeElement.children()[0].titleAsText(), 'database1');
    assert.strictEqual(indexedDBTreeElement.children()[0].childCount(), 0);
    const db2TreeElement = indexedDBTreeElement.children()[1];
    assert.strictEqual(db2TreeElement.titleAsText(), 'database2');
    assert.strictEqual(db2TreeElement.childCount(), 0);

    // 3. Create object store "objectStore1" with index "index1" in "database1"
    const os1 = new Application.IndexedDBModel.ObjectStore('objectStore1', 'test', false);
    os1.indexes.set('index1', new Application.IndexedDBModel.Index('index1', 'test', false, false));
    db1.objectStores.set('objectStore1', os1);
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(db1TreeElement.childCount(), 1);
    const os1TreeElement = db1TreeElement.children()[0];
    assert.strictEqual(os1TreeElement.titleAsText(), 'objectStore1');
    assert.strictEqual(os1TreeElement.childCount(), 1);
    const index1TreeElement = os1TreeElement.children()[0];
    assert.strictEqual(index1TreeElement.titleAsText(), 'index1');
    assert.strictEqual(db2TreeElement.childCount(), 0);

    // 4. Create object store "objectStore2" with index "index2" in "database1"
    const os2 = new Application.IndexedDBModel.ObjectStore('objectStore2', 'test', false);
    os2.indexes.set('index2', new Application.IndexedDBModel.Index('index2', 'test', false, false));
    db1.objectStores.set('objectStore2', os2);
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(db1TreeElement.childCount(), 2);
    assert.strictEqual(os1TreeElement.childCount(), 1);
    assert.strictEqual(os1TreeElement.children()[0].titleAsText(), 'index1');
    const os2TreeElement = db1TreeElement.children()[1];
    assert.strictEqual(os2TreeElement.titleAsText(), 'objectStore2');
    assert.strictEqual(os2TreeElement.childCount(), 1);
    const index2TreeElement = os2TreeElement.children()[0];
    assert.strictEqual(index2TreeElement.titleAsText(), 'index2');
    assert.strictEqual(db2TreeElement.childCount(), 0);

    // 5. Create index "index3" in "objectStore1" in "database1"
    os1.indexes.set('index3', new Application.IndexedDBModel.Index('index3', 'test', false, false));
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(os1TreeElement.childCount(), 2);
    assert.strictEqual(os1TreeElement.children()[0].titleAsText(), 'index1');
    assert.strictEqual(os1TreeElement.children()[1].titleAsText(), 'index3');
    assert.strictEqual(os2TreeElement.childCount(), 1);

    // 6. Delete index "index3" from "objectStore1" in "database1"
    os1.indexes.delete('index3');
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(os1TreeElement.childCount(), 1);
    assert.strictEqual(os1TreeElement.children()[0].titleAsText(), 'index1');

    // 7. Delete object store "objectStore2" from "database1"
    db1.objectStores.delete('objectStore2');
    model.dispatchEventToListeners(
        Application.IndexedDBModel.Events.DatabaseLoaded, {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(db1TreeElement.childCount(), 1);
    assert.strictEqual(os1TreeElement.titleAsText(), 'objectStore1');

    // 8. Delete database "database1"
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseRemoved, {databaseId: db1Id, model});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(indexedDBTreeElement.childCount(), 1);
    assert.strictEqual(indexedDBTreeElement.children()[0].titleAsText(), 'database2');
    assert.strictEqual(indexedDBTreeElement.children()[0].childCount(), 0);

    // 9. Delete database "database2"
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseRemoved, {databaseId: db2Id, model});
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.strictEqual(indexedDBTreeElement.childCount(), 0);
  });

  it('marks object store and index views as needing refresh on indexedDBContentUpdated', async () => {
    const MAIN_FRAME_ID = 'main' as Protocol.Page.FrameId;
    const storageKey = `test-storage-key|${MAIN_FRAME_ID}|http://www.example.com`;

    sinon.stub(model, 'loadObjectStoreData')
        .callsFake((_dbId, _storeName, _keyRange, _skipCount, _pageSize, callback) => {
          callback([], false);
        });
    sinon.stub(model, 'loadIndexData')
        .callsFake((_dbId, _storeName, _indexName, _keyRange, _skipCount, _pageSize, callback) => {
          callback([], false);
        });
    sinon.stub(model, 'getMetadata').resolves({entriesCount: 0, keyGeneratorValue: 0});

    const db1Id = new Application.IndexedDBModel.DatabaseId({storageKey}, 'database1');
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseAdded, {databaseId: db1Id, model});
    const db1 = new Application.IndexedDBModel.Database(db1Id, 1);
    const os1 = new Application.IndexedDBModel.ObjectStore('objectStore1', 'test', false);
    os1.indexes.set('index1', new Application.IndexedDBModel.Index('index1', 'test', false, false));
    db1.objectStores.set('objectStore1', os1);
    model.dispatchEventToListeners(Application.IndexedDBModel.Events.DatabaseLoaded,
                                   {database: db1, model, entriesUpdated: true});
    await new Promise(resolve => setTimeout(resolve, 0));

    const db1TreeElement =
        indexedDBTreeElement.children()[0] as Application.ApplicationPanelSidebar.IDBDatabaseTreeElement;
    const os1TreeElement =
        db1TreeElement.children()[0] as Application.ApplicationPanelSidebar.IDBObjectStoreTreeElement;
    const index1TreeElement = os1TreeElement.children()[0] as Application.ApplicationPanelSidebar.IDBIndexTreeElement;

    os1TreeElement.onselect(false);
    index1TreeElement.onselect(false);

    interface TreeElementWithView {
      view?: Application.IndexedDBViews.IDBDataView;
    }
    const os1View = (os1TreeElement as unknown as TreeElementWithView).view;
    const index1View = (index1TreeElement as unknown as TreeElementWithView).view;
    assert.exists(os1View);
    assert.exists(index1View);

    assert.isNull(os1View.element.querySelector('.stale-data-warning'));
    assert.isNull(index1View.element.querySelector('.stale-data-warning'));

    model.dispatchEventToListeners(Application.IndexedDBModel.Events.IndexedDBContentUpdated,
                                   {databaseId: db1Id, objectStoreName: 'objectStore1', model});

    assert.isNotNull(os1View.element.querySelector('.stale-data-warning'));
    assert.isNotNull(index1View.element.querySelector('.stale-data-warning'));

    os1View.refreshData();
    index1View.refreshData();
    await new Promise(resolve => setTimeout(resolve, 0));

    assert.isNull(os1View.element.querySelector('.stale-data-warning'));
    assert.isNull(index1View.element.querySelector('.stale-data-warning'));
  });
});

describe('Ask-AI Hover Floating Button', () => {
  setupLocaleHooks();

  let universe: TestUniverse;
  let target: SDK.Target.Target;
  let panel: Application.ResourcesPanel.ResourcesPanel;

  before(() => {
    UI.ActionRegistration.registerActionExtension({
      actionId: 'ai-assistance.storage-floating-button',
      category: UI.ActionRegistration.ActionCategory.GLOBAL,
      title: () => 'Ask Ai' as Common.UIString.LocalizedString,
    });
  });

  beforeEach(() => {
    universe = new TestUniverse();
    target = universe.createTarget({url: urlString`http://example.com/`});
    sinon.stub(target, 'inspectedURL').returns(urlString`http://example.com/`);
    sinon.stub(universe.targetManager, 'primaryPageTarget').returns(target);

    // Bridge legacy SDK and Settings singletons for legacy tree elements
    const {targetManager, settings} = universe;
    sinon.stub(SDK.TargetManager.TargetManager, 'instance').returns(targetManager);
    sinon.stub(Common.Settings.Settings, 'instance').returns(settings);

    const actionRegistry = UI.ActionRegistry.ActionRegistry.instance({forceNew: true});
    UI.ShortcutRegistry.ShortcutRegistry.instance({forceNew: true, actionRegistry});

    panel = sinon.createStubInstance(Application.ResourcesPanel.ResourcesPanel);
  });

  it('adds hover Ask-AI button for DOMStorageTreeElement', () => {
    const domStorageModel = target.model(SDK.DOMStorageModel.DOMStorageModel);
    assert.exists(domStorageModel);
    const domStorage = new SDK.DOMStorageModel.DOMStorage(domStorageModel, 'http://example.com/', true);
    const treeElement = new Application.ApplicationPanelSidebar.DOMStorageTreeElement(panel, domStorage);
    treeElement.onattach();

    const floatingButton = treeElement.listItemElement.querySelector('devtools-floating-button');
    assert.exists(floatingButton, 'Expected Ask-AI floating button on tree element');
  });

  it('adds hover Ask-AI button for CookieTreeElement', () => {
    const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
    assert.exists(resourceTreeModel);
    const frame = sinon.createStubInstance(SDK.ResourceTreeModel.ResourceTreeFrame);
    frame.resourceTreeModel.returns(resourceTreeModel);
    const cookieUrl = new Common.ParsedURL.ParsedURL('https://example.com/');
    const treeElement = new Application.ApplicationPanelSidebar.CookieTreeElement(panel, frame, cookieUrl);
    treeElement.onattach();
    const floatingButton = treeElement.listItemElement.querySelector('devtools-floating-button') ||
        treeElement.listItemElement.querySelector('button');
    assert.exists(floatingButton, 'Expected Ask-AI floating button on tree element');
  });

  it('adds hover Ask-AI button for general local storage', () => {
    const expandableTreeElement = new Application.ApplicationPanelTreeElement.ExpandableApplicationPanelTreeElement(
        panel, 'Local Storage', 'No local storage', 'Local Storage Description', 'local-storage');
    expandableTreeElement.onattach();
    const floatingButton = expandableTreeElement.listItemElement.querySelector('devtools-floating-button');
    assert.exists(floatingButton, 'Expected Ask-AI floating button on tree element');
  });
});

describe('Storage Agent Context Menu', () => {
  setupLocaleHooks();

  let universe: TestUniverse;
  let target: SDK.Target.Target;
  let panel: Application.ResourcesPanel.ResourcesPanel;
  let actionExecutedStub: sinon.SinonStub;

  before(() => {
    actionExecutedStub = sinon.stub();
    UI.ActionRegistration.registerActionExtension({
      actionId: 'ai-assistance.application-panel-context',
      category: UI.ActionRegistration.ActionCategory.GLOBAL,
      title: () => 'Debug with AI' as Common.UIString.LocalizedString,
      contextTypes() {
        return [AiAssistance.StorageItem.StorageItem];
      },
    });
    universe = new TestUniverse();
    target = universe.createTarget({url: urlString`http://example.com/`});
    panel = sinon.createStubInstance(Application.ResourcesPanel.ResourcesPanel);
  });

  beforeEach(() => {
    actionExecutedStub.resetHistory();
    sinon.stub(target, 'inspectedURL').returns(urlString`http://example.com/`);
    sinon.stub(universe.targetManager, 'primaryPageTarget').returns(target);
    sinon.stub(SDK.TargetManager.TargetManager, 'instance').returns(universe.targetManager);
    sinon.stub(Common.Settings.Settings, 'instance').returns(universe.settings);

    const actionRegistry = UI.ActionRegistry.ActionRegistry.instance({forceNew: true});
    UI.ShortcutRegistry.ShortcutRegistry.instance({forceNew: true, actionRegistry});
  });

  it('populates context menu with Debug with AI submenu and expected items for DOMStorageTreeElement', () => {
    const domStorageModel = target.model(SDK.DOMStorageModel.DOMStorageModel);
    assert.exists(domStorageModel);
    const domStorage = new SDK.DOMStorageModel.DOMStorage(domStorageModel, 'http://example.com/', true);
    const treeElement = new Application.ApplicationPanelSidebar.DOMStorageTreeElement(panel, domStorage);
    treeElement.onattach();

    const contextMenu = getContextMenuForElement(treeElement.listItemElement);
    const footerSection = contextMenu.footerSection();
    const debugWithAiItemInFooter = footerSection.items.find(item => item.buildDescriptor().label === 'Debug with AI');
    assert.exists(debugWithAiItemInFooter, 'Expected Debug with AI context menu item in footer section');

    const debugWithAiItem = contextMenu.buildDescriptor().subItems?.find(item => item.label === 'Debug with AI');
    assert.exists(debugWithAiItem, 'Expected Debug with AI context menu item');

    assert.deepEqual(debugWithAiItem.subItems?.map(item => item.label), ['Start a chat', 'Explain storage']);

    // Test primary action execution (Start a chat)
    const startChatSubItem = debugWithAiItem.subItems?.find(item => item.label === 'Start a chat');
    assert.exists(startChatSubItem?.id);
    contextMenu.invokeHandler(startChatSubItem.id);

    const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem);
    assert.exists(flavor);
    assert.instanceOf(flavor, AiAssistance.StorageItem.DOMStorageItem);
    assert.strictEqual((flavor as AiAssistance.StorageItem.DOMStorageItem).type, 'localStorage');
  });

  it('populates context menu with Debug with AI submenu and expected items for CookieTreeElement', () => {
    const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
    assert.exists(resourceTreeModel);
    const frame = sinon.createStubInstance(SDK.ResourceTreeModel.ResourceTreeFrame);
    frame.resourceTreeModel.returns(resourceTreeModel);
    const cookieUrl = new Common.ParsedURL.ParsedURL('https://example.com/');
    const treeElement = new Application.ApplicationPanelSidebar.CookieTreeElement(panel, frame, cookieUrl);
    treeElement.onattach();

    const contextMenu = getContextMenuForElement(treeElement.listItemElement);
    const footerSection = contextMenu.footerSection();
    const debugWithAiItemInFooter = footerSection.items.find(item => item.buildDescriptor().label === 'Debug with AI');
    assert.exists(debugWithAiItemInFooter, 'Expected Debug with AI context menu item in footer section');

    const debugWithAiItem = contextMenu.buildDescriptor().subItems?.find(item => item.label === 'Debug with AI');
    assert.exists(debugWithAiItem, 'Expected Debug with AI context menu item');

    assert.deepEqual(debugWithAiItem.subItems?.map(item => item.label), ['Start a chat', 'Explain cookies']);

    // Test secondary action execution (Explain cookies)
    const explainCookiesSubItem = debugWithAiItem.subItems?.find(item => item.label === 'Explain cookies');
    assert.exists(explainCookiesSubItem?.id);
    contextMenu.invokeHandler(explainCookiesSubItem.id);

    const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem);
    assert.exists(flavor);
    assert.instanceOf(flavor, AiAssistance.StorageItem.CookieItem);
    assert.strictEqual((flavor as AiAssistance.StorageItem.CookieItem).origin, 'https://example.com');
  });
});

describe('Storage Agent Selection', () => {
  setupLocaleHooks();

  let universe: TestUniverse;
  let target: SDK.Target.Target;
  let panel: Application.ResourcesPanel.ResourcesPanel;

  beforeEach(() => {
    universe = new TestUniverse();
    target = universe.createTarget({url: urlString`http://example.com/`});
    sinon.stub(target, 'inspectedURL').returns(urlString`http://example.com/`);
    sinon.stub(universe.targetManager, 'primaryPageTarget').returns(target);
    sinon.stub(SDK.TargetManager.TargetManager, 'instance').returns(universe.targetManager);
    sinon.stub(Common.Settings.Settings, 'instance').returns(universe.settings);

    panel = sinon.createStubInstance(Application.ResourcesPanel.ResourcesPanel);
  });

  it('sets active StorageItem flavor on DOMStorageTreeElement selection', () => {
    const domStorageModel = target.model(SDK.DOMStorageModel.DOMStorageModel);
    assert.exists(domStorageModel);
    const domStorage = new SDK.DOMStorageModel.DOMStorage(domStorageModel, 'http://example.com/', true);
    const treeOutline = new UI.TreeOutline.TreeOutlineInShadow();
    const treeElement = new Application.ApplicationPanelSidebar.DOMStorageTreeElement(panel, domStorage);
    treeOutline.appendChild(treeElement);

    // Clear flavor first
    UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, null);

    // Select the element
    treeElement.select();

    const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem);
    assert.exists(flavor);
    assert.instanceOf(flavor, AiAssistance.StorageItem.DOMStorageItem);
    assert.strictEqual((flavor as AiAssistance.StorageItem.DOMStorageItem).type, 'localStorage');
  });

  it('sets active StorageItem flavor on CookieTreeElement selection', () => {
    const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
    assert.exists(resourceTreeModel);
    const frame = sinon.createStubInstance(SDK.ResourceTreeModel.ResourceTreeFrame);
    frame.resourceTreeModel.returns(resourceTreeModel);
    const cookieUrl = new Common.ParsedURL.ParsedURL('https://example.com/');
    const treeOutline = new UI.TreeOutline.TreeOutlineInShadow();
    const treeElement = new Application.ApplicationPanelSidebar.CookieTreeElement(panel, frame, cookieUrl);
    treeOutline.appendChild(treeElement);

    // Clear flavor first
    UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, null);

    // Select the element
    treeElement.select();

    const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem);
    assert.exists(flavor);
    assert.instanceOf(flavor, AiAssistance.StorageItem.CookieItem);
    assert.strictEqual((flavor as AiAssistance.StorageItem.CookieItem).origin, 'https://example.com');
  });

  it('sets active DOMStorageItem flavor on Local Storage category selection', () => {
    const treeElement = new Application.ApplicationPanelTreeElement.ExpandableApplicationPanelTreeElement(
        panel, 'Local Storage', 'No local storage', 'Local Storage Description', 'local-storage');
    const treeOutline = new UI.TreeOutline.TreeOutlineInShadow();
    treeOutline.appendChild(treeElement);

    // Clear flavor first
    UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, null);

    // Select the element
    treeElement.select();

    const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem);
    assert.exists(flavor);
    assert.instanceOf(flavor, AiAssistance.StorageItem.DOMStorageItem);
    assert.strictEqual(flavor.origin, '');
    assert.isTrue(flavor.isGenericContext);
    assert.strictEqual(flavor.primaryTargetOrigin, 'http://example.com');
    assert.strictEqual((flavor as AiAssistance.StorageItem.DOMStorageItem).type, 'localStorage');
  });
});
