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

"use strict";

/**
 * Test the action of request details panel when filters are applied.
 * If there are any visible requests, the first request from the
 * list of visible requests should be displayed in the network
 * details panel
 * If there are no visible requests the panel should remain closed
 */

const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = [
  { url: "sjs_content-type-test-server.sjs?fmt=html&res=undefined&text=Sample" },
  { url: "sjs_content-type-test-server.sjs?fmt=css&text=sample" },
  { url: "sjs_content-type-test-server.sjs?fmt=js&text=sample" },
  { url: "sjs_content-type-test-server.sjs?fmt=font" },
  { url: "sjs_content-type-test-server.sjs?fmt=image" },
  { url: "sjs_content-type-test-server.sjs?fmt=audio" },
  { url: "sjs_content-type-test-server.sjs?fmt=video" },
  { url: "sjs_content-type-test-server.sjs?fmt=flash" },
  { url: "sjs_content-type-test-server.sjs?fmt=ws" },
];

add_task(async function () {
  let { monitor } = await initNetMonitor(FILTERING_URL);
  let { document, store, windowRequire } = monitor.panelWin;
  let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
  let {
    getSelectedRequest,
    getSortedRequests,
  } = windowRequire("devtools/client/netmonitor/src/selectors/index");

  store.dispatch(Actions.batchEnable(false));

  function setFreetextFilter(value) {
    store.dispatch(Actions.setRequestFilterText(value));
  }

  info("Starting test... ");

  let wait = waitForNetworkEvents(monitor, 9);
  loadFrameScriptUtils();
  await performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
  await wait;

  let toggleButton = document.querySelector(".network-details-panel-toggle");

  info("Test with the first request in the list visible");
  EventUtils.sendMouseEvent({ type: "click" },
      document.querySelector(".requests-list-filter-all-button"));
  testDetailsPanel(true, 0);

  info("Test with first request in the list not visible");
  EventUtils.sendMouseEvent({ type: "click" },
      document.querySelector(".requests-list-filter-all-button"));
  EventUtils.sendMouseEvent({ type: "click" },
      document.querySelector(".requests-list-filter-js-button"));
  testFilterButtons(monitor, "js");
  testDetailsPanel(true, 2);

  info("Test with no request in the list visible i.e. no request match the filters");
  EventUtils.sendMouseEvent({ type: "click" },
      document.querySelector(".requests-list-filter-all-button"));
  setFreetextFilter("foobar");
  // The network details panel should not open as there are no available requests visible
  testDetailsPanel(false);

  await teardown(monitor);

  function getSelectedIndex(state) {
    if (!state.requests.selectedId) {
      return -1;
    }
    return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
  }

  async function testDetailsPanel(shouldPanelOpen, selectedItemIndex = 0) {
    // Expected default state should be panel closed
    if (shouldPanelOpen) {
      // Toggle switch should be enabled only when there are visible requests
      is(toggleButton.hasAttribute("disabled"), false,
          "The pane toggle button should be enabled.");
    } else {
      is(toggleButton.hasAttribute("disabled"), true,
          "The pane toggle button should be disabled.");
    }

    is(toggleButton.classList.contains("pane-collapsed"), true,
        "The pane toggle button should still indicate that the details pane is " +
        "collapsed.");
    is(!!document.querySelector(".network-details-panel"), false,
        "The details pane should still be hidden.");
    is(getSelectedRequest(store.getState()), null,
        "There should still be no selected item in the requests menu.");

    // Trigger the details panel toggle action
    EventUtils.sendMouseEvent({ type: "click" }, toggleButton);

    if (shouldPanelOpen) {
      is(toggleButton.hasAttribute("disabled"), false,
          "The pane toggle button should still be enabled after being pressed.");
      is(toggleButton.classList.contains("pane-collapsed"), false,
          "The pane toggle button should now indicate that the details pane is " +
          "not collapsed anymore after being pressed.");
      is(!!document.querySelector(".network-details-panel"), true,
          "The details pane should not be hidden after toggle button was pressed.");
      isnot(getSelectedRequest(store.getState()), null,
          "There should be a selected item in the requests menu.");
      is(getSelectedIndex(store.getState()), selectedItemIndex,
          `The item index ${selectedItemIndex} should be selected in the requests menu.`);
      // Close the panel
      EventUtils.sendMouseEvent({ type: "click" }, toggleButton);
    } else {
      is(toggleButton.hasAttribute("disabled"), true,
          "The pane toggle button should be disabled.");
      is(toggleButton.classList.contains("pane-collapsed"), true,
          "The pane toggle button should still indicate that the details pane is " +
          "collapsed.");
      is(!!document.querySelector(".network-details-panel"), false,
          "The details pane should still be hidden.");
      is(getSelectedRequest(store.getState()), null,
          "There should still be no selected item in the requests menu.");
    }
  }
});
