/**
 * @license
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function() {
  'use strict';

  const Defs = {};

  /**
   * @typedef {{
   *    html: Node,
   *    position: number,
   *    length: number,
   * }}
   */
  Defs.CommentLinkItem;

  /**
   * Pattern describing URLs with supported protocols.
   * @type {RegExp}
   */
  const URL_PROTOCOL_PATTERN = /^(https?:\/\/|mailto:)/;

  /**
   * Construct a parser for linkifying text. Will linkify plain URLs that appear
   * in the text as well as custom links if any are specified in the linkConfig
   * parameter.
   * @param {Object|null|undefined} linkConfig Comment links as specified by the
   *     commentlinks field on a project config.
   * @param {Function} callback The callback to be fired when an intermediate
   *     parse result is emitted. The callback is passed text and href strings
   *     if a link is to be created, or a document fragment otherwise.
   * @param {boolean|undefined} opt_removeZeroWidthSpace If true, zero-width
   *     spaces will be removed from R=<email> and CC=<email> expressions.
   */
  function GrLinkTextParser(linkConfig, callback, opt_removeZeroWidthSpace) {
    this.linkConfig = linkConfig;
    this.callback = callback;
    this.removeZeroWidthSpace = opt_removeZeroWidthSpace;
    this.baseUrl = Gerrit.BaseUrlBehavior.getBaseUrl();
    Object.preventExtensions(this);
  }

  /**
   * Emit a callback to create a link element.
   * @param {string} text The text of the link.
   * @param {string} href The URL to use as the href of the link.
   */
  GrLinkTextParser.prototype.addText = function(text, href) {
    if (!text) { return; }
    this.callback(text, href);
  };

  /**
   * Given the source text and a list of CommentLinkItem objects that were
   * generated by the commentlinks config, emit parsing callbacks.
   * @param {string} text The chuml of source text over which the outputArray
   *     items range.
   * @param {!Array<Defs.CommentLinkItem>} outputArray The list of items to add
   *     resulting from commentlink matches.
   */
  GrLinkTextParser.prototype.processLinks = function(text, outputArray) {
    this.sortArrayReverse(outputArray);
    const fragment = document.createDocumentFragment();
    let cursor = text.length;

    // Start inserting linkified URLs from the end of the String. That way, the
    // string positions of the items don't change as we iterate through.
    outputArray.forEach(item => {
      // Add any text between the current linkified item and the item added
      // before if it exists.
      if (item.position + item.length !== cursor) {
        fragment.insertBefore(
            document.createTextNode(
                text.slice(item.position + item.length, cursor)),
            fragment.firstChild);
      }
      fragment.insertBefore(item.html, fragment.firstChild);
      cursor = item.position;
    });

    // Add the beginning portion at the end.
    if (cursor !== 0) {
      fragment.insertBefore(
          document.createTextNode(text.slice(0, cursor)), fragment.firstChild);
    }

    this.callback(null, null, fragment);
  };

  /**
   * Sort the given array of CommentLinkItems such that the positions are in
   * reverse order.
   * @param {!Array<Defs.CommentLinkItem>} outputArray
   */
  GrLinkTextParser.prototype.sortArrayReverse = function(outputArray) {
    outputArray.sort((a, b) => b.position - a.position);
  };

  /**
   * Create a CommentLinkItem and append it to the given output array. This
   * method can be called in either of two ways:
   * - With `text` and `href` parameters provided, and the `html` parameter
   *   passed as `null`. In this case, the new CommentLinkItem will be a link
   *   element with the given text and href value.
   * - With the `html` paremeter provided, and the `text` and `href` parameters
   *   passed as `null`. In this case, the string of HTML will be parsed and the
   *   first resulting node will be used as the resulting content.
   * @param {string|null} text The text to use if creating a link.
   * @param {string|null} href The href to use as the URL if creating a link.
   * @param {string|null} html The html to parse and use as the result.
   * @param {number} position The position inside the source text where the item
   *     starts.
   * @param {number} length The number of characters in the source text
   *     represented by the item.
   * @param {!Array<Defs.CommentLinkItem>} outputArray The array to which the
   *     new item is to be appended.
   */
  GrLinkTextParser.prototype.addItem =
      function(text, href, html, position, length, outputArray) {
        let htmlOutput = '';

        if (href) {
          const a = document.createElement('a');
          a.href = href;
          a.textContent = text;
          a.target = '_blank';
          a.rel = 'noopener';
          htmlOutput = a;
        } else if (html) {
          const fragment = document.createDocumentFragment();
          // Create temporary div to hold the nodes in.
          const div = document.createElement('div');
          div.innerHTML = html;
          while (div.firstChild) {
            fragment.appendChild(div.firstChild);
          }
          htmlOutput = fragment;
        }

        outputArray.push({
          html: htmlOutput,
          position,
          length,
        });
      };

  /**
   * Create a CommentLinkItem for a link and append it to the given output
   * array.
   * @param {string|null} text The text for the link.
   * @param {string|null} href The href to use as the URL of the link.
   * @param {number} position The position inside the source text where the link
   *     starts.
   * @param {number} length The number of characters in the source text
   *     represented by the link.
   * @param {!Array<Defs.CommentLinkItem>} outputArray The array to which the
   *     new item is to be appended.
   */
  GrLinkTextParser.prototype.addLink =
      function(text, href, position, length, outputArray) {
        if (!text || this.hasOverlap(position, length, outputArray)) { return; }
        if (!!this.baseUrl && href.startsWith('/') &&
             !href.startsWith(this.baseUrl)) {
          href = this.baseUrl + href;
        }
        this.addItem(text, href, null, position, length, outputArray);
      };

  /**
   * Create a CommentLinkItem specified by an HTMl string and append it to the
   * given output array.
   * @param {string|null} html The html to parse and use as the result.
   * @param {number} position The position inside the source text where the item
   *     starts.
   * @param {number} length The number of characters in the source text
   *     represented by the item.
   * @param {!Array<Defs.CommentLinkItem>} outputArray The array to which the
   *     new item is to be appended.
   */
  GrLinkTextParser.prototype.addHTML =
      function(html, position, length, outputArray) {
        if (this.hasOverlap(position, length, outputArray)) { return; }
        if (!!this.baseUrl && html.match(/<a href=\"\//g) &&
             !new RegExp(`<a href="${this.baseUrl}`, 'g').test(html)) {
          html = html.replace(/<a href=\"\//g, `<a href=\"${this.baseUrl}\/`);
        }
        this.addItem(null, null, html, position, length, outputArray);
      };

  /**
   * Does the given range overlap with anything already in the item list.
   * @param {number} position
   * @param {number} length
   * @param {!Array<Defs.CommentLinkItem>} outputArray
   */
  GrLinkTextParser.prototype.hasOverlap =
      function(position, length, outputArray) {
        const endPosition = position + length;
        for (let i = 0; i < outputArray.length; i++) {
          const arrayItemStart = outputArray[i].position;
          const arrayItemEnd = outputArray[i].position + outputArray[i].length;
          if ((position >= arrayItemStart && position < arrayItemEnd) ||
        (endPosition > arrayItemStart && endPosition <= arrayItemEnd) ||
        (position === arrayItemStart && position === arrayItemEnd)) {
            return true;
          }
        }
        return false;
      };

  /**
   * Parse the given source text and emit callbacks for the items that are
   * parsed.
   * @param {string} text
   */
  GrLinkTextParser.prototype.parse = function(text) {
    linkify(text, {
      callback: this.parseChunk.bind(this),
    });
  };

  /**
   * Callback that is pased into the linkify function. ba-linkify will call this
   * method in either of two ways:
   * - With both a `text` and `href` parameter provided: this indicates that
   *   ba-linkify has found a plain URL and wants it linkified.
   * - With only a `text` parameter provided: this represents the non-link
   *   content that lies between the links the library has found.
   * @param {string} text
   * @param {string|null|undefined} href
   */
  GrLinkTextParser.prototype.parseChunk = function(text, href) {
    // TODO(wyatta) switch linkify sequence, see issue 5526.
    if (this.removeZeroWidthSpace) {
      // Remove the zero-width space added in gr-change-view.
      text = text.replace(/^(CC|R)=\u200B/gm, '$1=');
    }

    // If the href is provided then ba-linkify has recognized it as a URL. If
    // the source text does not include a protocol, the protocol will be added
    // by ba-linkify. Create the link if the href is provided and its protocol
    // matches the expected pattern.
    if (href && URL_PROTOCOL_PATTERN.test(href)) {
      this.addText(text, href);
    } else {
      // For the sections of text that lie between the links found by
      // ba-linkify, we search for the project-config-specified link patterns.
      this.parseLinks(text, this.linkConfig);
    }
  };

  /**
   * Walk over the given source text to find matches for comemntlink patterns
   * and emit parse result callbacks.
   * @param {string} text The raw source text.
   * @param {Object|null|undefined} patterns A comment links specification
   *   object.
   */
  GrLinkTextParser.prototype.parseLinks = function(text, patterns) {
    // The outputArray is used to store all of the matches found for all
    // patterns.
    const outputArray = [];
    for (const p in patterns) {
      if (patterns[p].enabled != null && patterns[p].enabled == false) {
        continue;
      }
      // PolyGerrit doesn't use hash-based navigation like the GWT UI.
      // Account for this.
      if (patterns[p].html) {
        patterns[p].html =
            patterns[p].html.replace(/<a href=\"#\//g, '<a href="/');
      } else if (patterns[p].link) {
        if (patterns[p].link[0] == '#') {
          patterns[p].link = patterns[p].link.substr(1);
        }
      }

      const pattern = new RegExp(patterns[p].match, 'g');

      let match;
      let textToCheck = text;
      let susbtrIndex = 0;

      while ((match = pattern.exec(textToCheck)) != null) {
        textToCheck = textToCheck.substr(match.index + match[0].length);
        let result = match[0].replace(pattern,
            patterns[p].html || patterns[p].link);

        let i;
        // Skip portion of replacement string that is equal to original.
        for (i = 0; i < result.length; i++) {
          if (result[i] !== match[0][i]) { break; }
        }
        result = result.slice(i);

        if (patterns[p].html) {
          this.addHTML(
              result,
              susbtrIndex + match.index + i,
              match[0].length - i,
              outputArray);
        } else if (patterns[p].link) {
          this.addLink(
              match[0],
              result,
              susbtrIndex + match.index + i,
              match[0].length - i,
              outputArray);
        } else {
          throw Error('linkconfig entry ' + p +
              ' doesn’t contain a link or html attribute.');
        }

        // Update the substring location so we know where we are in relation to
        // the initial full text string.
        susbtrIndex = susbtrIndex + match.index + match[0].length;
      }
    }
    this.processLinks(text, outputArray);
  };

  window.GrLinkTextParser = GrLinkTextParser;
})();
