// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

let lastChanged = null;
let lastFocused = null;
const restartButton = $('experiment-restart-button');

/** @type {?function():void} */
let experimentalFeaturesResolver = null;

/** @type {!Promise} */
const experimentalFeaturesReady = new Promise(resolve => {
  experimentalFeaturesResolver = resolve;
});

/**
 * This variable structure is here to document the structure that the template
 * expects to correctly populate the page.
 */

/**
 * Takes the |experimentalFeaturesData| input argument which represents data
 * about all the current feature entries and populates the html jstemplate with
 * that data. It expects an object structure like the above.
 * @param {!ExperimentalFeaturesData} experimentalFeaturesData Information about
 *     all experiments. See returnFlagsExperiments() for the structure of this
 * object.
 */
function renderTemplate(experimentalFeaturesData) {
  const templateToProcess = jstGetTemplate('tab-content-available-template');
  const context = new JsEvalContext(experimentalFeaturesData);
  const content = $('tab-content-available');

  // Duplicate the template into the content area.
  // This prevents the misrendering of available flags when the template
  // is rerendered. Example - resetting flags.
  content.textContent = '';
  content.appendChild(templateToProcess);

  // Process the templates: available / unavailable flags.
  jstProcess(context, templateToProcess);

  // Unavailable flags are not shown on iOS.
  const unavailableTemplate = $('tab-content-unavailable');
  if (unavailableTemplate) {
    jstProcess(context, $('tab-content-unavailable'));
  }

  showRestartToast(experimentalFeaturesData.needsRestart);

  // Add handlers to dynamically created HTML elements.
  let elements = document.getElementsByClassName('experiment-select');
  for (const element of elements) {
    element.onchange = function() {
      const selectElement = /** @type {!HTMLSelectElement} */ (element);
      handleSelectExperimentalFeatureChoice(
          selectElement, selectElement.selectedIndex);
      lastChanged = element;
      return false;
    };
    registerFocusEvents(element);
  }

  elements = document.getElementsByClassName('experiment-enable-disable');
  for (const element of elements) {
    element.onchange = function() {
      const selectElement = /** @type {!HTMLSelectElement} */ (element);
      handleEnableExperimentalFeature(
          selectElement,
          selectElement.options[selectElement.selectedIndex].value ==
              'enabled');
      lastChanged = selectElement;
      return false;
    };
    registerFocusEvents(element);
  }

  elements = document.getElementsByClassName('experiment-origin-list-value');
  for (const element of elements) {
    element.onchange = function() {
      handleSetOriginListFlag(element, element.value);
      return false;
    };
  }

  assert(restartButton || cr.isIOS);
  if (restartButton) {
    restartButton.onclick = restartBrowser;
  }

  // Tab panel selection.
  const tabEls = document.getElementsByClassName('tab');
  for (let i = 0; i < tabEls.length; ++i) {
    tabEls[i].addEventListener('click', function(e) {
      e.preventDefault();
      for (let j = 0; j < tabEls.length; ++j) {
        tabEls[j].parentNode.classList.toggle('selected', tabEls[j] === this);
        tabEls[j].setAttribute('aria-selected', tabEls[j] === this);
      }
      FlagSearch.getInstance().announceSearchResults();
    });
  }

  const smallScreenCheck = window.matchMedia('(max-width: 480px)');
  // Toggling of experiment description overflow content on smaller screens.
  if(smallScreenCheck.matches){
    elements = document.querySelectorAll('.experiment .flex:first-child');
    for (const element of elements) {
      element.onclick = () => element.classList.toggle('expand');
    }
  }

  $('experiment-reset-all').onclick = resetAllFlags;

  highlightReferencedFlag();
  const search = FlagSearch.getInstance();
  search.init();
}

/**
 * Add events to an element in order to keep track of the last focused element.
 * Focus restart button if a previous focus target has been set and tab key
 * pressed.
 * @param {Element} el Element to bind events to.
 */
function registerFocusEvents(el) {
  el.addEventListener('keydown', function(e) {
    if (lastChanged && e.key === 'Tab' && !e.shiftKey) {
      lastFocused = lastChanged;
      e.preventDefault();
      restartButton.focus();
    }
  });
  el.addEventListener('blur', function() {
    lastChanged = null;
  });
}

/**
 * Highlight an element associated with the page's location's hash. We need to
 * fake fragment navigation with '.scrollIntoView()', since the fragment IDs
 * don't actually exist until after the template code runs; normal navigation
 * therefore doesn't work.
 */
function highlightReferencedFlag() {
  if (window.location.hash) {
    const el = document.querySelector(window.location.hash);
    if (el && !el.classList.contains('referenced')) {
      // Unhighlight whatever's highlighted.
      if (document.querySelector('.referenced')) {
        document.querySelector('.referenced').classList.remove('referenced');
      }
      // Highlight the referenced element.
      el.classList.add('referenced');

      // Switch to unavailable tab if the flag is in this section.
      if ($('tab-content-unavailable').contains(el)) {
        $('tab-available').parentNode.classList.remove('selected');
        $('tab-available').setAttribute('aria-selected', 'false');
        $('tab-unavailable').parentNode.classList.add('selected');
        $('tab-unavailable').setAttribute('aria-selected', 'true');
      }
      el.scrollIntoView();
    }
  }
}

/**
 * Gets details and configuration about the available features. The
 * |returnExperimentalFeatures()| will be called with reply.
 */
function requestExperimentalFeaturesData() {
  chrome.send('requestExperimentalFeatures');
}

/** Restart browser and restore tabs. */
function restartBrowser() {
  chrome.send('restartBrowser');
}

/**
 * Cause a text string to be announced by screen readers
 * @param {string} text The text that should be announced.
*/
function announceStatus(text) {
  $('screen-reader-status-message').textContent = '';
  setTimeout(function() {
    $('screen-reader-status-message').textContent = text;
  }, 100);
}

/** Reset all flags to their default values and refresh the UI. */
function resetAllFlags() {
  chrome.send('resetAllFlags');
  FlagSearch.getInstance().clearSearch();
  announceStatus(loadTimeData.getString("reset-acknowledged"));
  showRestartToast(true);
  requestExperimentalFeaturesData();
}

/**
 * Show the restart toast.
 * @param {boolean} show Setting to toggle showing / hiding the toast.
 */
function showRestartToast(show) {
  $('needs-restart').classList.toggle('show', show);
  const restartButton = $('experiment-restart-button');
  if (restartButton) {
    restartButton.setAttribute("tabindex", show ? '9' : '-1');
  }
  if (show) {
    $('needs-restart').setAttribute("role", "alert");
  }
}

/**
 * @typedef {{
 *    internal_name: string,
 *    name: string,
 *    description: string,
 *    enabled: boolean,
 *    is_default: boolean,
 *    choices: ?Array<{internal_name: string, description: string, selected:
 * boolean}>, supported_platforms: !Array<string>
 * }}
 */
let Feature;

/**
 * @typedef {{
 *  supportedFeatures: !Array<!Feature>,
 *  unsupportedFeatures: !Array<!Feature>,
 *  needsRestart: boolean,
 *  showBetaChannelPromotion: boolean,
 *  showDevChannelPromotion: boolean,
 *  showOwnerWarning: boolean
 * }}
 */
let ExperimentalFeaturesData;

/**
 * Called by the WebUI to re-populate the page with data representing the
 * current state of all experimental features.
 * @param {ExperimentalFeaturesData} experimentalFeaturesData Information about
 *     all experimental
 *    features in the following format:
 *   {
 *     supportedFeatures: [
 *       {
 *         internal_name: 'Feature ID string',
 *         name: 'Feature name',
 *         description: 'Description',
 *         // enabled and default are only set if the feature is single valued.
 *         // enabled is true if the feature is currently enabled.
 *         // is_default is true if the feature is in its default state.
 *         enabled: true,
 *         is_default: false,
 *         // choices is only set if the entry has multiple values.
 *         choices: [
 *           {
 *             internal_name: 'Experimental feature ID string',
 *             description: 'description',
 *             selected: true
 *           }
 *         ],
 *         supported_platforms: [
 *           'Mac',
 *           'Linux'
 *         ],
 *       }
 *     ],
 *     unsupportedFeatures: [
 *       // Mirrors the format of |supportedFeatures| above.
 *     ],
 *     needsRestart: false,
 *     showBetaChannelPromotion: false,
 *     showDevChannelPromotion: false,
 *     showOwnerWarning: false
 *   }
 */
function returnExperimentalFeatures(experimentalFeaturesData) {
  const bodyContainer = $('body-container');
  renderTemplate(experimentalFeaturesData);

  if (experimentalFeaturesData.showBetaChannelPromotion) {
    $('channel-promo-beta').hidden = false;
  } else if (experimentalFeaturesData.showDevChannelPromotion) {
    $('channel-promo-dev').hidden = false;
  }

  $('promos').hidden = !experimentalFeaturesData.showBetaChannelPromotion &&
      !experimentalFeaturesData.showDevChannelPromotion;

  bodyContainer.style.visibility = 'visible';
  const ownerWarningDiv = $('owner-warning');
  if (ownerWarningDiv) {
    ownerWarningDiv.hidden = !experimentalFeaturesData.showOwnerWarning;
  }

  experimentalFeaturesResolver();
}

/**
 * Handles updating the UI after experiment selections have been made.
 * Adds or removes experiment highlighting depending on whether the experiment
 * is set to the default option then shows the restart button.
 * @param {HTMLElement} node The select node for the experiment being changed.
 * @param {number} index The selected option index.
 */
function experimentChangesUiUpdates(node, index) {
  const selected = node.options[index];
  /** @suppress {missingProperties} */
  const experimentContainerEl = $(node.internal_name).firstElementChild;
  const isDefault =
      ('default' in selected.dataset && selected.dataset.default === '1') ||
      (!('default' in selected.dataset) && index === 0);
  experimentContainerEl.classList.toggle('experiment-default', isDefault);
  experimentContainerEl.classList.toggle('experiment-switched', !isDefault);

  showRestartToast(true);
}

/**
 * Handles a 'enable' or 'disable' button getting clicked.
 * @param {HTMLElement} node The node for the experiment being changed.
 * @param {boolean} enable Whether to enable or disable the experiment.
 * @suppress {missingProperties}
 */
function handleEnableExperimentalFeature(node, enable) {
  /* This function is an onchange handler, which can be invoked during page
   * restore - see https://crbug.com/1038638. */
  if (!node.internal_name) {
    return;
  }
  chrome.send('enableExperimentalFeature', [String(node.internal_name),
                                            String(enable)]);
  experimentChangesUiUpdates(node, enable ? 1 : 0);
}

/** @suppress {missingProperties} */
function handleSetOriginListFlag(node, value) {
  /* This function is an onchange handler, which can be invoked during page
   * restore - see https://crbug.com/1038638. */
  if (!node.internal_name) {
    return;
  }
  chrome.send('setOriginListFlag', [String(node.internal_name), String(value)]);
  showRestartToast(true);
}

/**
 * Invoked when the selection of a multi-value choice is changed to the
 * specified index.
 * @param {HTMLElement} node The node for the experiment being changed.
 * @param {number} index The index of the option that was selected.
 * @suppress {missingProperties}
 */
function handleSelectExperimentalFeatureChoice(node, index) {
  /* This function is an onchange handler, which can be invoked during page
   * restore - see https://crbug.com/1038638. */
  if (!node.internal_name) {
    return;
  }
  chrome.send('enableExperimentalFeature',
              [String(node.internal_name) + '@' + index, 'true']);
  experimentChangesUiUpdates(node, index);
}

/** @type {!FlagSearch.SearchContent} */
const emptySearchContent = Object.freeze({
  link: null,
  title: null,
  description: null,
});

/**
 * Handles in page searching. Matches against the experiment flag name.
 * @constructor
 */
const FlagSearch = function() {
  FlagSearch.instance_ = this;

  /** @private {!FlagSearch.SearchContent} */
  this.experiments_ = /** @type {FlagSearch.SearchContent} */ (
      Object.assign({}, emptySearchContent));

  /** @private {!FlagSearch.SearchContent} */
  this.unavailableExperiments_ = /** @type {FlagSearch.SearchContent} */ (
      Object.assign({}, emptySearchContent));

  this.searchBox_ = $('search');
  this.noMatchMsg_ = document.querySelectorAll('.tab-content .no-match');

  /** @private {?number} */
  this.searchIntervalId_ = null;

  this.initialized = false;
};

// Delay in ms following a keypress, before a search is made.
FlagSearch.SEARCH_DEBOUNCE_TIME_MS = 150;

/**
 * Object definition for storing the elements which are searched on.
 * @typedef {{
 *   description: ?NodeList<!HTMLElement>,
 *   link: ?NodeList<!HTMLElement>,
 *   title: ?NodeList<!HTMLElement>
 * }}
 */
FlagSearch.SearchContent;

/**
 * Get the singleton instance of FlagSearch.
 * @return {Object} Instance of FlagSearch.
 */
FlagSearch.getInstance = function() {
  if (FlagSearch.instance_) {
    return FlagSearch.instance_;
  } else {
    return new FlagSearch();
  }
};

FlagSearch.prototype = {
  /**
   * Initialises the in page search. Adding searchbox listeners and
   * collates the text elements used for string matching.
   */
  init() {
    this.experiments_.link = /** @type {!NodeList<!HTMLElement>} */ (
        document.querySelectorAll('#tab-content-available .permalink'));
    this.experiments_.title = /** @type {!NodeList<!HTMLElement>} */ (
        document.querySelectorAll('#tab-content-available .experiment-name'));
    this.experiments_.description = /** @type {!NodeList<!HTMLElement>} */ (
        document.querySelectorAll('#tab-content-available p'));

    this.unavailableExperiments_.link = /** @type {!NodeList<!HTMLElement>} */ (
        document.querySelectorAll('#tab-content-unavailable .permalink'));
    this.unavailableExperiments_.title =
        /** @type {!NodeList<!HTMLElement>} */ (document.querySelectorAll(
            '#tab-content-unavailable .experiment-name'));
    this.unavailableExperiments_.description =
        /** @type {!NodeList<!HTMLElement>} */ (
            document.querySelectorAll('#tab-content-unavailable p'));

    if (!this.initialized) {
      this.searchBox_.addEventListener('input', this.debounceSearch.bind(this));

      document.querySelector('.clear-search').addEventListener('click',
          this.clearSearch.bind(this));

      window.addEventListener('keyup', function(e) {
        if (document.activeElement.nodeName === 'TEXTAREA') {
          return;
        }
        switch (e.key) {
          case '/':
            this.searchBox_.focus();
            break;
          case 'Escape':
          case 'Enter':
            this.searchBox_.blur();
            break;
        }
      }.bind(this));
      this.searchBox_.focus();
      this.initialized = true;
    }
  },

  /**
   * Clears a search showing all experiments.
   */
  clearSearch() {
    this.searchBox_.value = '';
    this.doSearch();
  },

  /**
   * Reset existing highlights on an element.
   * @param {HTMLElement} el The element to remove all highlighted mark up on.
   * @param {string} text Text to reset the element's textContent to.
   */
  resetHighlights(el, text) {
    if (el.children) {
      el.textContent = text;
    }
  },

  /**
   * Highlights the search term within a given element.
   * @param {string} searchTerm Search term user entered.
   * @param {HTMLElement} el The node containing the text to match against.
   * @return {boolean} Whether there was a match.
   */
  highlightMatchInElement(searchTerm, el) {
    // Experiment container.
    const parentEl = el.parentNode.parentNode.parentNode;
    const text = el.textContent;
    const match = text.toLowerCase().indexOf(searchTerm);

    parentEl.classList.toggle('hidden', match === -1);

    if (match === -1) {
      this.resetHighlights(el, text);
      return false;
    }

    if (searchTerm !== '') {
      // Clear all nodes.
      el.textContent = '';

      if (match > 0) {
        const textNodePrefix =
            document.createTextNode(text.substring(0, match));
        el.appendChild(textNodePrefix);
      }

      const matchEl = document.createElement('mark');
      matchEl.textContent = text.substr(match, searchTerm.length);
      el.appendChild(matchEl);

      const matchSuffix = text.substring(match + searchTerm.length);
      if (matchSuffix) {
        const textNodeSuffix = document.createTextNode(matchSuffix);
        el.appendChild(textNodeSuffix);
      }
    } else {
      this.resetHighlights(el, text);
    }
    return true;
  },

  /**
   * Goes through all experiment text and highlights the relevant matches.
   * Only the first instance of a match in each experiment text block is
   * highlighted. This prevents the sea of yellow that happens using the global
   * find in page search.
   * @param {FlagSearch.SearchContent} searchContent Object containing the
   *     experiment text elements to search against.
   * @param {string} searchTerm
   * @return {number} The number of matches found.
   */
  highlightAllMatches(searchContent, searchTerm) {
    let matches = 0;
    for (let i = 0, j = searchContent.link.length; i < j; i++) {
      if (this.highlightMatchInElement(searchTerm, searchContent.title[i])) {
        this.resetHighlights(searchContent.description[i],
            searchContent.description[i].textContent);
        this.resetHighlights(searchContent.link[i],
            searchContent.link[i].textContent);
        matches++;
        continue;
      }
      if (this.highlightMatchInElement(searchTerm,
          searchContent.description[i])) {
        this.resetHighlights(searchContent.title[i],
            searchContent.title[i].textContent);
        this.resetHighlights(searchContent.link[i],
            searchContent.link[i].textContent);
        matches++;
        continue;
      }
      // Match links, replace spaces with hyphens as flag names don't
      // have spaces.
      if (this.highlightMatchInElement(searchTerm.replace(/\s/, '-'),
          searchContent.link[i])) {
        this.resetHighlights(searchContent.title[i],
            searchContent.title[i].textContent);
        this.resetHighlights(searchContent.description[i],
            searchContent.description[i].textContent);
        matches++;
      }
    }
    return matches;
  },

  /**
   * Performs a search against the experiment title, description, permalink.
   */
  doSearch() {
    const searchTerm = this.searchBox_.value.trim().toLowerCase();

    if (searchTerm || searchTerm === '') {
      document.body.classList.toggle('searching', searchTerm);
      // Available experiments
      this.noMatchMsg_[0].classList.toggle(
          'hidden',
          this.highlightAllMatches(this.experiments_, searchTerm) > 0);
      // Unavailable experiments
      this.noMatchMsg_[1].classList.toggle(
          'hidden',
          this.highlightAllMatches(this.unavailableExperiments_, searchTerm) >
              0);
      this.announceSearchResults();
    }

    this.searchIntervalId_ = null;
  },

  announceSearchResults() {
    const searchTerm = this.searchBox_.value.trim().toLowerCase();
    if (!searchTerm) {
      return;
    }

    let tabAvailable = true;
    const tabEls = document.getElementsByClassName('tab');
    for (let i = 0; i < tabEls.length; ++i) {
      if (tabEls[i].parentNode.classList.contains('selected')) {
        tabAvailable = tabEls[i].id === 'tab-available';
      }
    }
    const seletedTabId =
        tabAvailable ? '#tab-content-available' : '#tab-content-unavailable';
    const queryString = seletedTabId + ' .experiment:not(.hidden)';
    const total = document.querySelectorAll(queryString).length;
    if (total) {
      announceStatus(
          total === 1 ?
              loadTimeData.getStringF('searchResultsSingular', searchTerm) :
              loadTimeData.getStringF(
                  'searchResultsPlural', total, searchTerm));
    }
  },

  /**
   * Debounces the search to improve performance and prevent too many searches
   * from being initiated.
   */
  debounceSearch() {
    if (this.searchIntervalId_) {
      clearTimeout(this.searchIntervalId_);
    }
    this.searchIntervalId_ = setTimeout(this.doSearch.bind(this),
        FlagSearch.SEARCH_DEBOUNCE_TIME_MS);
  }
};

/**
 * Allows the restart button to jump back to the previously focused experiment
 * in the list instead of going to the top of the page.
 */
function setupRestartButton() {
  restartButton.addEventListener('keydown', function(e) {
    if (e.shiftKey && e.key === 'Tab' && lastFocused) {
      e.preventDefault();
      lastFocused.focus();
    }
  });
  restartButton.addEventListener('blur', () => {
    lastFocused = null;
  });
}

document.addEventListener('DOMContentLoaded', function() {
  // Get and display the data upon loading.
  requestExperimentalFeaturesData();
  setupRestartButton();
  cr.ui.FocusOutlineManager.forDocument(document);
});

// Update the highlighted flag when the hash changes.
window.addEventListener('hashchange', highlightReferencedFlag);
