// Copyright 2016 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.

cr.exportPath('settings');

/**
 * A data structure used by callers to combine the results of multiple search
 * requests.
 *
 * @typedef {{
 *   canceled: Boolean,
 *   didFindMatches: Boolean,
 *   wasClearSearch: Boolean,
 * }}
 */
settings.SearchResult;

cr.define('settings', function() {
  /**
   * A CSS attribute indicating that a node should be ignored during searching.
   * @type {string}
   */
  const SKIP_SEARCH_CSS_ATTRIBUTE = 'no-search';

  /**
   * List of elements types that should not be searched at all.
   * The only DOM-MODULE node is in <body> which is not searched, therefore
   * DOM-MODULE is not needed in this set.
   * @type {!Set<string>}
   */
  const IGNORED_ELEMENTS = new Set([
    'CONTENT',
    'CR-ACTION-MENU',
    'CR-DIALOG',
    'CR-SLIDER',
    'DIALOG',
    'IMG',
    'IRON-ICON',
    'IRON-LIST',
    'PAPER-ICON-BUTTON',
    'PAPER-ICON-BUTTON-LIGHT',
    'PAPER-RIPPLE',
    'PAPER-SPINNER-LITE',
    'SLOT',
    'STYLE',
    'TEMPLATE',
  ]);

  /**
   * Traverses the entire DOM (including Shadow DOM), finds text nodes that
   * match the given regular expression and applies the highlight UI. It also
   * ensures that <settings-section> instances become visible if any matches
   * occurred under their subtree.
   *
   * @param {!settings.SearchRequest} request
   * @param {!Node} root The root of the sub-tree to be searched
   * @private
   */
  function findAndHighlightMatches_(request, root) {
    let foundMatches = false;
    const highlights = [];
    const bubbles = [];

    const domIfTag = Polymer.DomIf ? 'DOM-IF' : 'TEMPLATE';

    function doSearch(node) {
      // NOTE: For subpage wrappers <template route-path="..."> when |no-search|
      // participates in a data binding:
      //
      //  - Always use noSearch Polymer property, for example
      //    no-search="[[foo]]"
      //  - *Don't* use a no-search CSS attribute like no-search$="[[foo]]"
      //
      // The latter throws an error during the automatic Polymer 2 conversion to
      // <dom-if><template...></dom-if> syntax.
      // TODO(dpapad):Clean this up once Polymer 2 migration has finished.
      if (node.nodeName == domIfTag && node.hasAttribute('route-path') &&
          !node.if && !node['noSearch'] &&
          !node.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE)) {
        request.queue_.addRenderTask(new RenderTask(request, node));
        return;
      }

      if (IGNORED_ELEMENTS.has(node.nodeName))
        return;

      if (node instanceof HTMLElement) {
        const element = /** @type {HTMLElement} */ (node);
        if (element.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE) ||
            element.hasAttribute('hidden') || element.style.display == 'none') {
          return;
        }
      }

      if (node.nodeType == Node.TEXT_NODE) {
        const textContent = node.nodeValue.trim();
        if (textContent.length == 0)
          return;

        if (request.regExp.test(textContent)) {
          foundMatches = true;
          const bubble = revealParentSection_(node, request.rawQuery_);
          if (bubble)
            bubbles.push(bubble);

          // Don't highlight <select> nodes, yellow rectangles can't be
          // displayed within an <option>.
          // TODO(dpapad): highlight <select> controls with a search bubble
          // instead.
          if (node.parentNode.nodeName != 'OPTION') {
            request.addTextObserver(node);
            highlights.push(cr.search_highlight_utils.highlight(
                node, textContent.split(request.regExp)));
          }
        }
        // Returning early since TEXT_NODE nodes never have children.
        return;
      }

      let child = node.firstChild;
      while (child !== null) {
        // Getting a reference to the |nextSibling| before calling doSearch()
        // because |child| could be removed from the DOM within doSearch().
        const nextSibling = child.nextSibling;
        doSearch(child);
        child = nextSibling;
      }

      const shadowRoot = node.shadowRoot;
      if (shadowRoot)
        doSearch(shadowRoot);
    }

    doSearch(root);
    request.addHighlightsAndBubbles(highlights, bubbles);
    return foundMatches;
  }

  /**
   * Finds and makes visible the <settings-section> parent of |node|.
   * @param {!Node} node
   * @param {string} rawQuery
   * @return {?Node} The search bubble created while revealing the section, if
   *     any.
   * @private
   */
  function revealParentSection_(node, rawQuery) {
    let associatedControl = null;
    // Find corresponding SETTINGS-SECTION parent and make it visible.
    let parent = node;
    while (parent && parent.nodeName !== 'SETTINGS-SECTION') {
      parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
          parent.host :
          parent.parentNode;
      if (parent.nodeName == 'SETTINGS-SUBPAGE') {
        // TODO(dpapad): Cast to SettingsSubpageElement here.
        associatedControl = assert(
            parent.associatedControl,
            'An associated control was expected for SETTINGS-SUBPAGE ' +
                parent.pageTitle + ', but was not found.');
      }
    }
    if (parent)
      parent.hiddenBySearch = false;

    // Need to add the search bubble after the parent SETTINGS-SECTION has
    // become visible, otherwise |offsetWidth| returns zero.
    if (associatedControl) {
      return cr.search_highlight_utils.highlightControlWithBubble(
          associatedControl, rawQuery);
    }
    return null;
  }

  /** @abstract */
  class Task {
    /**
     * @param {!settings.SearchRequest} request
     * @param {!Node} node
     */
    constructor(request, node) {
      /** @protected {!settings.SearchRequest} */
      this.request = request;

      /** @protected {!Node} */
      this.node = node;
    }

    /**
     * @abstract
     * @return {!Promise}
     */
    exec() {}
  }

  class RenderTask extends Task {
    /**
     * A task that takes a <template is="dom-if">...</template> node
     * corresponding to a setting subpage and renders it. A
     * SearchAndHighlightTask is posted for the newly rendered subtree, once
     * rendering is done.
     *
     * @param {!settings.SearchRequest} request
     * @param {!Node} node
     */
    constructor(request, node) {
      super(request, node);
    }

    /** @override */
    exec() {
      const routePath = this.node.getAttribute('route-path');

      const content = Polymer.DomIf ?
          Polymer.DomIf._contentForTemplate(this.node.firstElementChild) :
          /** @type {{_content: DocumentFragment}} */ (this.node)._content;
      const subpageTemplate = content.querySelector('settings-subpage');
      subpageTemplate.setAttribute('route-path', routePath);
      assert(!this.node.if);
      this.node.if = true;

      return new Promise((resolve, reject) => {
        const parent = this.node.parentNode;
        parent.async(() => {
          const renderedNode =
              parent.querySelector('[route-path="' + routePath + '"]');
          // Register a SearchAndHighlightTask for the part of the DOM that was
          // just rendered.
          this.request.queue_.addSearchAndHighlightTask(
              new SearchAndHighlightTask(this.request, assert(renderedNode)));
          resolve();
        });
      });
    }
  }

  class SearchAndHighlightTask extends Task {
    /**
     * @param {!settings.SearchRequest} request
     * @param {!Node} node
     */
    constructor(request, node) {
      super(request, node);
    }

    /** @override */
    exec() {
      const foundMatches = findAndHighlightMatches_(this.request, this.node);
      this.request.updateMatches(foundMatches);
      return Promise.resolve();
    }
  }

  class TopLevelSearchTask extends Task {
    /**
     * @param {!settings.SearchRequest} request
     * @param {!Node} page
     */
    constructor(request, page) {
      super(request, page);
    }

    /** @override */
    exec() {
      const shouldSearch = this.request.regExp !== null;
      this.setSectionsVisibility_(!shouldSearch);
      if (shouldSearch) {
        const foundMatches = findAndHighlightMatches_(this.request, this.node);
        this.request.updateMatches(foundMatches);
      }

      return Promise.resolve();
    }

    /**
     * @param {boolean} visible
     * @private
     */
    setSectionsVisibility_(visible) {
      const sections = this.node.querySelectorAll('settings-section');

      for (let i = 0; i < sections.length; i++)
        sections[i].hiddenBySearch = !visible;
    }
  }

  class TaskQueue {
    /** @param {!settings.SearchRequest} request */
    constructor(request) {
      /** @private {!settings.SearchRequest} */
      this.request_ = request;

      /**
       * @private {{
       *   high: !Array<!Task>,
       *   middle: !Array<!Task>,
       *   low: !Array<!Task>
       * }}
       */
      this.queues_;
      this.reset();

      /** @private {?Function} */
      this.onEmptyCallback_ = null;

      /**
       * Whether a task is currently running.
       * @private {boolean}
       */
      this.running_ = false;
    }

    /** Drops all tasks. */
    reset() {
      this.queues_ = {high: [], middle: [], low: []};
    }

    /** @param {!TopLevelSearchTask} task */
    addTopLevelSearchTask(task) {
      this.queues_.high.push(task);
      this.consumePending_();
    }

    /** @param {!SearchAndHighlightTask} task */
    addSearchAndHighlightTask(task) {
      this.queues_.middle.push(task);
      this.consumePending_();
    }

    /** @param {!RenderTask} task */
    addRenderTask(task) {
      this.queues_.low.push(task);
      this.consumePending_();
    }

    /**
     * Registers a callback to be called every time the queue becomes empty.
     * @param {function():void} onEmptyCallback
     */
    onEmpty(onEmptyCallback) {
      this.onEmptyCallback_ = onEmptyCallback;
    }

    /**
     * @return {!Task|undefined}
     * @private
     */
    popNextTask_() {
      return this.queues_.high.shift() || this.queues_.middle.shift() ||
          this.queues_.low.shift();
    }

    /** @private */
    consumePending_() {
      if (this.running_)
        return;

      const task = this.popNextTask_();
      if (!task) {
        this.running_ = false;
        if (this.onEmptyCallback_)
          this.onEmptyCallback_();
        return;
      }

      this.running_ = true;
      window.requestIdleCallback(() => {
        if (!this.request_.canceled) {
          task.exec().then(() => {
            this.running_ = false;
            this.consumePending_();
          });
        }
        // Nothing to do otherwise. Since the request corresponding to this
        // queue was canceled, the queue is disposed along with the request.
      });
    }
  }

  class SearchRequest {
    /**
     * @param {string} rawQuery
     * @param {!Element} root
     */
    constructor(rawQuery, root) {
      /** @private {string} */
      this.rawQuery_ = rawQuery;

      /** @private {!Element} */
      this.root_ = root;

      /** @type {?RegExp} */
      this.regExp = this.generateRegExp_();

      /**
       * Whether this request was canceled before completing.
       * @type {boolean}
       */
      this.canceled = false;

      /** @private {boolean} */
      this.foundMatches_ = false;

      /** @type {!PromiseResolver} */
      this.resolver = new PromiseResolver();

      /** @private {!TaskQueue} */
      this.queue_ = new TaskQueue(this);
      this.queue_.onEmpty(() => {
        this.resolver.resolve(this);
      });

      /** @private {!Set<!MutationObserver>} */
      this.textObservers_ = new Set();

      /** @private {!Array<!Node>} */
      this.highlights_ = [];

      /** @private {!Array<!Node>} */
      this.bubbles_ = [];
    }

    /**
     * @param {!Array<!Node>} highlights The highlight wrappers to add
     * @param {!Array<!Node>} bubbles The search bubbles to add.
     */
    addHighlightsAndBubbles(highlights, bubbles) {
      this.highlights_.push.apply(this.highlights_, highlights);
      this.bubbles_.push.apply(this.bubbles_, bubbles);
    }

    removeAllTextObservers() {
      this.textObservers_.forEach(observer => {
        observer.disconnect();
      });
      this.textObservers_.clear();
    }

    removeAllHighlightsAndBubbles() {
      cr.search_highlight_utils.removeHighlights(this.highlights_);
      for (const bubble of this.bubbles_)
        bubble.remove();
      this.highlights_ = [];
      this.bubbles_ = [];
    }

    /** @param {!Node} textNode */
    addTextObserver(textNode) {
      const originalParentNode = /** @type {!Node} */ (textNode.parentNode);
      const observer = new MutationObserver(mutations => {
        const oldValue = mutations[0].oldValue.trim();
        const newValue = textNode.nodeValue.trim();
        if (oldValue != newValue) {
          observer.disconnect();
          this.textObservers_.delete(observer);
          cr.search_highlight_utils.findAndRemoveHighlights(originalParentNode);
        }
      });
      observer.observe(
          textNode, {characterData: true, characterDataOldValue: true});
      this.textObservers_.add(observer);
    }

    /**
     * Fires this search request.
     */
    start() {
      this.queue_.addTopLevelSearchTask(
          new TopLevelSearchTask(this, this.root_));
    }

    /**
     * @return {?RegExp}
     * @private
     */
    generateRegExp_() {
      let regExp = null;

      // Generate search text by escaping any characters that would be
      // problematic for regular expressions.
      const searchText = this.rawQuery_.trim().replace(SANITIZE_REGEX, '\\$&');
      if (searchText.length > 0)
        regExp = new RegExp(`(${searchText})`, 'i');

      return regExp;
    }

    /**
     * @param {string} rawQuery
     * @return {boolean} Whether this SearchRequest refers to an identical
     *     query.
     */
    isSame(rawQuery) {
      return this.rawQuery_ == rawQuery;
    }

    /**
     * Updates the result for this search request.
     * @param {boolean} found
     */
    updateMatches(found) {
      this.foundMatches_ = this.foundMatches_ || found;
    }

    /** @return {boolean} Whether any matches were found. */
    didFindMatches() {
      return this.foundMatches_;
    }
  }

  /** @type {!RegExp} */
  const SANITIZE_REGEX = /[-[\]{}()*+?.,\\^$|#\s]/g;

  /** @interface */
  class SearchManager {
    /**
     * @param {string} text The text to search for.
     * @param {!Element} page
     * @return {!Promise<!settings.SearchRequest>} A signal indicating that
     *     searching finished.
     */
    search(text, page) {}
  }

  /** @implements {SearchManager} */
  class SearchManagerImpl {
    constructor() {
      /** @private {!Set<!settings.SearchRequest>} */
      this.activeRequests_ = new Set();

      /** @private {!Set<!settings.SearchRequest>} */
      this.completedRequests_ = new Set();

      /** @private {?string} */
      this.lastSearchedText_ = null;
    }

    /** @override */
    search(text, page) {
      // Cancel any pending requests if a request with different text is
      // submitted.
      if (text != this.lastSearchedText_) {
        this.activeRequests_.forEach(function(request) {
          request.removeAllTextObservers();
          request.removeAllHighlightsAndBubbles();
          request.canceled = true;
          request.resolver.resolve(request);
        });
        this.activeRequests_.clear();
        this.completedRequests_.forEach(request => {
          request.removeAllTextObservers();
          request.removeAllHighlightsAndBubbles();
        });
        this.completedRequests_.clear();
      }

      this.lastSearchedText_ = text;
      const request = new SearchRequest(text, page);
      this.activeRequests_.add(request);
      request.start();
      return request.resolver.promise.then(() => {
        this.activeRequests_.delete(request);
        this.completedRequests_.add(request);
        return request;
      });
    }
  }

  /** @type {?SearchManager} */
  let instance = null;

  /** @return {!SearchManager} */
  function getSearchManager() {
    if (instance === null)
      instance = new SearchManagerImpl();
    return instance;
  }

  /**
   * Sets the SearchManager singleton instance, useful for testing.
   * @param {!SearchManager} searchManager
   */
  function setSearchManagerForTesting(searchManager) {
    instance = searchManager;
  }

  return {
    getSearchManager: getSearchManager,
    setSearchManagerForTesting: setSearchManagerForTesting,
    SearchRequest: SearchRequest,
  };
});
