/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Check "Show tabbing order" works as expected when used with the iframe picker

const TEST_URI = `https://example.com/document-builder.sjs?html=
    <button id=top-btn-1>Top level button before iframe</button>
    <iframe src="https://example.org/document-builder.sjs?html=${encodeURIComponent(`
      <button id=iframe-btn-1>in iframe button 1</button>
      <button id=iframe-btn-2>in iframe button 2</button>
    `)}"></iframe>
    <button id=top-btn-2>Top level button after iframe</button>`;

add_task(async () => {
  const env = await addTestTab(TEST_URI);
  const { doc, panel, store, toolbox, win } = env;

  const topLevelFrameHighlighterTestFront =
    await toolbox.target.getFront("highlighterTest");

  const iframeTarget = toolbox.commands.targetCommand
    .getAllTargets([toolbox.commands.targetCommand.TYPES.FRAME])
    .find(t => t.url.startsWith("https://example.org"));

  const iframeHighlighterTestFront = iframeTarget
    ? await iframeTarget.getFront("highlighterTest")
    : null;

  const topLevelAccessibilityFrontActorID =
    panel.accessibilityProxy.accessibilityFront.actorID;

  const iframeAccessibilityFrontActorID = iframeTarget
    ? (await iframeTarget.getFront("accessibility")).actorID
    : null;

  info(`Click on "Show Tabbing Order" checkbox`);
  const tabbingOrderCheckbox = doc.getElementById(
    "devtools-display-tabbing-order-checkbox"
  );
  tabbingOrderCheckbox.click();
  await waitUntilState(store, state => state.ui.tabbingOrderDisplayed === true);

  is(tabbingOrderCheckbox.checked, true, "Checkbox is checked");
  let tabbingOrderHighlighterData =
    await topLevelFrameHighlighterTestFront.getTabbingOrderHighlighterData(
      topLevelAccessibilityFrontActorID
    );
  // ⚠️ We don't get the highlighter for the <html> node of the iframe when Fission is enabled.
  // This should be fix as part of Bug 1740509.
  is(
    JSON.stringify(tabbingOrderHighlighterData),
    JSON.stringify([`button#top-btn-1 : 1`, `button#top-btn-2 : 4`]),
    "Tabbing order is visible for the top level target after clicking the checkbox"
  );

  let iframeTabingOrderHighlighterData =
    await iframeHighlighterTestFront.getTabbingOrderHighlighterData(
      iframeAccessibilityFrontActorID
    );

  is(
    JSON.stringify(iframeTabingOrderHighlighterData),
    JSON.stringify([`button#iframe-btn-1 : 2`, `button#iframe-btn-2 : 3`]),
    "Tabbing order is visible for the top level target after clicking the checkbox"
  );

  info("Select the iframe in the iframe picker");
  // Get the iframe picker items
  const menuList = toolbox.doc.getElementById("toolbox-frame-menu");

  const frames = Array.from(menuList.querySelectorAll(".command"));

  let onInitialized = win.once(win.EVENTS.INITIALIZED);
  frames[1].click();
  await onInitialized;
  await waitUntilState(
    store,
    state => state.ui.tabbingOrderDisplayed === false
  );

  is(
    tabbingOrderCheckbox.checked,
    false,
    "Checkbox is unchecked after selecting an iframe"
  );

  tabbingOrderHighlighterData =
    await topLevelFrameHighlighterTestFront.getTabbingOrderHighlighterData(
      topLevelAccessibilityFrontActorID
    );
  is(
    tabbingOrderHighlighterData.length,
    0,
    "Tabbing order is not visible anymore"
  );

  info(
    `Click on "Show Tabbing Order" checkbox and check that highlighter is only displayed for selected frame`
  );
  tabbingOrderCheckbox.click();
  await waitUntilState(store, state => state.ui.tabbingOrderDisplayed === true);

  tabbingOrderHighlighterData =
    await topLevelFrameHighlighterTestFront.getTabbingOrderHighlighterData(
      topLevelAccessibilityFrontActorID
    );
  is(
    tabbingOrderHighlighterData.length,
    0,
    "There's no highlighter displayed on the top level target when focused on specific iframe"
  );

  iframeTabingOrderHighlighterData =
    await iframeHighlighterTestFront.getTabbingOrderHighlighterData(
      iframeAccessibilityFrontActorID
    );

  is(
    JSON.stringify(iframeTabingOrderHighlighterData),
    JSON.stringify([`button#iframe-btn-1 : 1`, `button#iframe-btn-2 : 2`]),
    "Tabbing order has expected data when a specific iframe is selected"
  );

  info("Select the top level document back");
  onInitialized = win.once(win.EVENTS.INITIALIZED);
  toolbox.doc.querySelector("#toolbox-frame-menu .command").click();
  await onInitialized;

  is(
    tabbingOrderCheckbox.checked,
    false,
    "Checkbox is unchecked after selecting the top level frame"
  );
  await waitUntilState(
    store,
    state => state.ui.tabbingOrderDisplayed === false
  );

  tabbingOrderHighlighterData =
    await topLevelFrameHighlighterTestFront.getTabbingOrderHighlighterData(
      topLevelAccessibilityFrontActorID
    );
  iframeTabingOrderHighlighterData =
    await iframeHighlighterTestFront.getTabbingOrderHighlighterData(
      iframeAccessibilityFrontActorID
    );

  is(
    iframeTabingOrderHighlighterData.length,
    0,
    "Highlighter is hidden on the frame after selecting back the top level target"
  );

  await closeTabToolboxAccessibility(env.tab);
});
