/**
 * @license
 * Copyright (C) 2016 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.
 */
import '../../../scripts/bundled-polymer.js';

import '../../shared/gr-lib-loader/gr-lib-loader.js';
import '../../../scripts/util.js';
import '../gr-diff/gr-diff-line.js';
import '../gr-diff-highlight/gr-annotation.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-syntax-layer_html.js';

const LANGUAGE_MAP = {
  'application/dart': 'dart',
  'application/json': 'json',
  'application/x-powershell': 'powershell',
  'application/typescript': 'typescript',
  'application/xml': 'xml',
  'application/xquery': 'xquery',
  'application/x-erb': 'erb',
  'text/css': 'css',
  'text/html': 'html',
  'text/javascript': 'js',
  'text/jsx': 'jsx',
  'text/x-c': 'cpp',
  'text/x-c++src': 'cpp',
  'text/x-clojure': 'clojure',
  'text/x-cmake': 'cmake',
  'text/x-coffeescript': 'coffeescript',
  'text/x-common-lisp': 'lisp',
  'text/x-crystal': 'crystal',
  'text/x-csharp': 'csharp',
  'text/x-csrc': 'cpp',
  'text/x-d': 'd',
  'text/x-diff': 'diff',
  'text/x-django': 'django',
  'text/x-dockerfile': 'dockerfile',
  'text/x-ebnf': 'ebnf',
  'text/x-elm': 'elm',
  'text/x-erlang': 'erlang',
  'text/x-fortran': 'fortran',
  'text/x-fsharp': 'fsharp',
  'text/x-go': 'go',
  'text/x-groovy': 'groovy',
  'text/x-haml': 'haml',
  'text/x-handlebars': 'handlebars',
  'text/x-haskell': 'haskell',
  'text/x-haxe': 'haxe',
  'text/x-ini': 'ini',
  'text/x-java': 'java',
  'text/x-julia': 'julia',
  'text/x-kotlin': 'kotlin',
  'text/x-latex': 'latex',
  'text/x-less': 'less',
  'text/x-lua': 'lua',
  'text/x-mathematica': 'mathematica',
  'text/x-nginx-conf': 'nginx',
  'text/x-nsis': 'nsis',
  'text/x-objectivec': 'objectivec',
  'text/x-ocaml': 'ocaml',
  'text/x-perl': 'perl',
  'text/x-pgsql': 'pgsql', // postgresql
  'text/x-php': 'php',
  'text/x-properties': 'properties',
  'text/x-protobuf': 'protobuf',
  'text/x-puppet': 'puppet',
  'text/x-python': 'python',
  'text/x-q': 'q',
  'text/x-ruby': 'ruby',
  'text/x-rustsrc': 'rust',
  'text/x-scala': 'scala',
  'text/x-scss': 'scss',
  'text/x-scheme': 'scheme',
  'text/x-shell': 'shell',
  'text/x-soy': 'soy',
  'text/x-spreadsheet': 'excel',
  'text/x-sh': 'bash',
  'text/x-sql': 'sql',
  'text/x-swift': 'swift',
  'text/x-systemverilog': 'sv',
  'text/x-tcl': 'tcl',
  'text/x-torque': 'torque',
  'text/x-twig': 'twig',
  'text/x-vb': 'vb',
  'text/x-verilog': 'v',
  'text/x-vhdl': 'vhdl',
  'text/x-yaml': 'yaml',
  'text/vbscript': 'vbscript',
};
const ASYNC_DELAY = 10;

const CLASS_WHITELIST = {
  'gr-diff gr-syntax gr-syntax-attr': true,
  'gr-diff gr-syntax gr-syntax-attribute': true,
  'gr-diff gr-syntax gr-syntax-built_in': true,
  'gr-diff gr-syntax gr-syntax-comment': true,
  'gr-diff gr-syntax gr-syntax-doctag': true,
  'gr-diff gr-syntax gr-syntax-function': true,
  'gr-diff gr-syntax gr-syntax-keyword': true,
  'gr-diff gr-syntax gr-syntax-link': true,
  'gr-diff gr-syntax gr-syntax-literal': true,
  'gr-diff gr-syntax gr-syntax-meta': true,
  'gr-diff gr-syntax gr-syntax-meta-keyword': true,
  'gr-diff gr-syntax gr-syntax-name': true,
  'gr-diff gr-syntax gr-syntax-number': true,
  'gr-diff gr-syntax gr-syntax-params': true,
  'gr-diff gr-syntax gr-syntax-regexp': true,
  'gr-diff gr-syntax gr-syntax-selector-attr': true,
  'gr-diff gr-syntax gr-syntax-selector-class': true,
  'gr-diff gr-syntax gr-syntax-selector-id': true,
  'gr-diff gr-syntax gr-syntax-selector-pseudo': true,
  'gr-diff gr-syntax gr-syntax-selector-tag': true,
  'gr-diff gr-syntax gr-syntax-string': true,
  'gr-diff gr-syntax gr-syntax-tag': true,
  'gr-diff gr-syntax gr-syntax-template-tag': true,
  'gr-diff gr-syntax gr-syntax-template-variable': true,
  'gr-diff gr-syntax gr-syntax-title': true,
  'gr-diff gr-syntax gr-syntax-type': true,
  'gr-diff gr-syntax gr-syntax-variable': true,
};

const CPP_DIRECTIVE_WITH_LT_PATTERN = /^\s*#(if|define).*</;
const CPP_WCHAR_PATTERN = /L\'(\\)?.\'/g;
const JAVA_PARAM_ANNOT_PATTERN = /(@[^\s]+)\(([^)]+)\)/g;
const GO_BACKSLASH_LITERAL = '\'\\\\\'';
const GLOBAL_LT_PATTERN = /</g;

/** @extends Polymer.Element */
class GrSyntaxLayer extends GestureEventListeners(
    LegacyElementMixin(
        PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-syntax-layer'; }

  static get properties() {
    return {
      diff: {
        type: Object,
        observer: '_diffChanged',
      },
      enabled: {
        type: Boolean,
        value: true,
      },
      _baseRanges: {
        type: Array,
        value() { return []; },
      },
      _revisionRanges: {
        type: Array,
        value() { return []; },
      },
      _baseLanguage: String,
      _revisionLanguage: String,
      _listeners: {
        type: Array,
        value() { return []; },
      },
      /** @type {?number} */
      _processHandle: Number,
      /**
       * The promise last returned from `process()` while the asynchronous
       * processing is running - `null` otherwise. Provides a `cancel()`
       * method that rejects it with `{isCancelled: true}`.
       *
       * @type {?Object}
       */
      _processPromise: {
        type: Object,
        value: null,
      },
      _hljs: Object,
    };
  }

  addListener(fn) {
    this.push('_listeners', fn);
  }

  removeListener(fn) {
    this._listeners = this._listeners.filter(f => f != fn);
  }

  /**
   * Annotation layer method to add syntax annotations to the given element
   * for the given line.
   *
   * @param {!HTMLElement} el
   * @param {!HTMLElement} lineNumberEl
   * @param {!Object} line (GrDiffLine)
   */
  annotate(el, lineNumberEl, line) {
    if (!this.enabled) { return; }

    // Determine the side.
    let side;
    if (line.type === GrDiffLine.Type.REMOVE || (
      line.type === GrDiffLine.Type.BOTH &&
        el.getAttribute('data-side') !== 'right')) {
      side = 'left';
    } else if (line.type === GrDiffLine.Type.ADD || (
      el.getAttribute('data-side') !== 'left')) {
      side = 'right';
    }

    // Find the relevant syntax ranges, if any.
    let ranges = [];
    if (side === 'left' && this._baseRanges.length >= line.beforeNumber) {
      ranges = this._baseRanges[line.beforeNumber - 1] || [];
    } else if (side === 'right' &&
        this._revisionRanges.length >= line.afterNumber) {
      ranges = this._revisionRanges[line.afterNumber - 1] || [];
    }

    // Apply the ranges to the element.
    for (const range of ranges) {
      GrAnnotation.annotateElement(
          el, range.start, range.length, range.className);
    }
  }

  _getLanguage(diffFileMetaInfo) {
    // The Gerrit API provides only content-type, but for other users of
    // gr-diff it may be more convenient to specify the language directly.
    return diffFileMetaInfo.language ||
        LANGUAGE_MAP[diffFileMetaInfo.content_type];
  }

  /**
   * Start processing syntax for the loaded diff and notify layer listeners
   * as syntax info comes online.
   *
   * @return {Promise}
   */
  process() {
    // Cancel any still running process() calls, because they append to the
    // same _baseRanges and _revisionRanges fields.
    this._cancel();

    // Discard existing ranges.
    this._baseRanges = [];
    this._revisionRanges = [];

    if (!this.enabled || !this.diff.content.length) {
      return Promise.resolve();
    }

    if (this.diff.meta_a) {
      this._baseLanguage = this._getLanguage(this.diff.meta_a);
    }
    if (this.diff.meta_b) {
      this._revisionLanguage = this._getLanguage(this.diff.meta_b);
    }
    if (!this._baseLanguage && !this._revisionLanguage) {
      return Promise.resolve();
    }

    const state = {
      sectionIndex: 0,
      lineIndex: 0,
      baseContext: undefined,
      revisionContext: undefined,
      lineNums: {left: 1, right: 1},
      lastNotify: {left: 1, right: 1},
    };

    const rangesCache = new Map();

    this._processPromise = util.makeCancelable(this._loadHLJS()
        .then(() => new Promise(resolve => {
          const nextStep = () => {
            this._processHandle = null;
            this._processNextLine(state, rangesCache);

            // Move to the next line in the section.
            state.lineIndex++;

            // If the section has been exhausted, move to the next one.
            if (this._isSectionDone(state)) {
              state.lineIndex = 0;
              state.sectionIndex++;
            }

            // If all sections have been exhausted, finish.
            if (state.sectionIndex >= this.diff.content.length) {
              resolve();
              this._notify(state);
              return;
            }

            if (state.lineIndex % 100 === 0) {
              this._notify(state);
              this._processHandle = this.async(nextStep, ASYNC_DELAY);
            } else {
              nextStep.call(this);
            }
          };

          this._processHandle = this.async(nextStep, 1);
        })));
    return this._processPromise
        .finally(() => { this._processPromise = null; });
  }

  /**
   * Cancel any asynchronous syntax processing jobs.
   */
  _cancel() {
    if (this._processHandle != null) {
      this.cancelAsync(this._processHandle);
      this._processHandle = null;
    }
    if (this._processPromise) {
      this._processPromise.cancel();
    }
  }

  _diffChanged() {
    this._cancel();
    this._baseRanges = [];
    this._revisionRanges = [];
  }

  /**
   * Take a string of HTML with the (potentially nested) syntax markers
   * Highlight.js emits and emit a list of text ranges and classes for the
   * markers.
   *
   * @param {string} str The string of HTML.
   * @param {Map<string, !Array<!Object>>} rangesCache A map for caching
   * ranges for each string. A cache is read and written by this method.
   * Since diff is mostly comparing same file on two sides, there is good rate
   * of duplication at least for parts that are on left and right parts.
   * @return {!Array<!Object>} The list of ranges.
   */
  _rangesFromString(str, rangesCache) {
    const cached = rangesCache.get(str);
    if (cached) return cached;

    const div = document.createElement('div');
    div.innerHTML = str;
    const ranges = this._rangesFromElement(div, 0);
    rangesCache.set(str, ranges);
    return ranges;
  }

  _rangesFromElement(elem, offset) {
    let result = [];
    for (const node of elem.childNodes) {
      const nodeLength = GrAnnotation.getLength(node);
      // Note: HLJS may emit a span with class undefined when it thinks there
      // may be a syntax error.
      if (node.tagName === 'SPAN' && node.className !== 'undefined') {
        if (CLASS_WHITELIST.hasOwnProperty(node.className)) {
          result.push({
            start: offset,
            length: nodeLength,
            className: node.className,
          });
        }
        if (node.children.length) {
          result = result.concat(this._rangesFromElement(node, offset));
        }
      }
      offset += nodeLength;
    }
    return result;
  }

  /**
   * For a given state, process the syntax for the next line (or pair of
   * lines).
   *
   * @param {!Object} state The processing state for the layer.
   */
  _processNextLine(state, rangesCache) {
    let baseLine;
    let revisionLine;

    const section = this.diff.content[state.sectionIndex];
    if (section.ab) {
      baseLine = section.ab[state.lineIndex];
      revisionLine = section.ab[state.lineIndex];
      state.lineNums.left++;
      state.lineNums.right++;
    } else {
      if (section.a && section.a.length > state.lineIndex) {
        baseLine = section.a[state.lineIndex];
        state.lineNums.left++;
      }
      if (section.b && section.b.length > state.lineIndex) {
        revisionLine = section.b[state.lineIndex];
        state.lineNums.right++;
      }
    }

    // To store the result of the syntax highlighter.
    let result;

    if (this._baseLanguage && baseLine !== undefined &&
        this._hljs.getLanguage(this._baseLanguage)) {
      baseLine = this._workaround(this._baseLanguage, baseLine);
      result = this._hljs.highlight(this._baseLanguage, baseLine, true,
          state.baseContext);
      this.push('_baseRanges',
          this._rangesFromString(result.value, rangesCache));
      state.baseContext = result.top;
    }

    if (this._revisionLanguage && revisionLine !== undefined &&
        this._hljs.getLanguage(this._revisionLanguage)) {
      revisionLine = this._workaround(this._revisionLanguage, revisionLine);
      result = this._hljs.highlight(this._revisionLanguage, revisionLine,
          true, state.revisionContext);
      this.push('_revisionRanges',
          this._rangesFromString(result.value, rangesCache));
      state.revisionContext = result.top;
    }
  }

  /**
   * Ad hoc fixes for HLJS parsing bugs. Rewrite lines of code in constrained
   * cases before sending them into HLJS so that they parse correctly.
   *
   * Important notes:
   * * These tests should be as constrained as possible to avoid interfering
   *   with code it shouldn't AND to avoid executing regexes as much as
   *   possible.
   * * These tests should document the issue clearly enough that the test can
   *   be condidently removed when the issue is solved in HLJS.
   * * These tests should rewrite the line of code to have the same number of
   *   characters. This method rewrites the string that gets parsed, but NOT
   *   the string that gets displayed and highlighted. Thus, the positions
   *   must be consistent.
   *
   * @param {!string} language The name of the HLJS language plugin in use.
   * @param {!string} line The line of code to potentially rewrite.
   * @return {string} A potentially-rewritten line of code.
   */
  _workaround(language, line) {
    if (language === 'cpp') {
      /**
       * Prevent confusing < and << operators for the start of a meta string
       * by converting them to a different operator.
       * {@see Issue 4864}
       * {@see https://github.com/isagalaev/highlight.js/issues/1341}
       */
      if (CPP_DIRECTIVE_WITH_LT_PATTERN.test(line)) {
        line = line.replace(GLOBAL_LT_PATTERN, '|');
      }

      /**
       * Rewrite CPP wchar_t characters literals to wchar_t string literals
       * because HLJS only understands the string form.
       * {@see Issue 5242}
       * {#see https://github.com/isagalaev/highlight.js/issues/1412}
       */
      if (CPP_WCHAR_PATTERN.test(line)) {
        line = line.replace(CPP_WCHAR_PATTERN, 'L"$1."');
      }

      return line;
    }

    /**
     * Prevent confusing the closing paren of a parameterized Java annotation
     * being applied to a formal argument as the closing paren of the argument
     * list. Rewrite the parens as spaces.
     * {@see Issue 4776}
     * {@see https://github.com/isagalaev/highlight.js/issues/1324}
     */
    if (language === 'java' && JAVA_PARAM_ANNOT_PATTERN.test(line)) {
      return line.replace(JAVA_PARAM_ANNOT_PATTERN, '$1 $2 ');
    }

    /**
     * HLJS misunderstands backslash character literals in Go.
     * {@see Issue 5007}
     * {#see https://github.com/isagalaev/highlight.js/issues/1411}
     */
    if (language === 'go' && line.includes(GO_BACKSLASH_LITERAL)) {
      return line.replace(GO_BACKSLASH_LITERAL, '"\\\\"');
    }

    return line;
  }

  /**
   * Tells whether the state has exhausted its current section.
   *
   * @param {!Object} state
   * @return {boolean}
   */
  _isSectionDone(state) {
    const section = this.diff.content[state.sectionIndex];
    if (section.ab) {
      return state.lineIndex >= section.ab.length;
    } else {
      return (!section.a || state.lineIndex >= section.a.length) &&
          (!section.b || state.lineIndex >= section.b.length);
    }
  }

  /**
   * For a given state, notify layer listeners of any processed line ranges
   * that have not yet been notified.
   *
   * @param {!Object} state
   */
  _notify(state) {
    if (state.lineNums.left - state.lastNotify.left) {
      this._notifyRange(
          state.lastNotify.left,
          state.lineNums.left,
          'left');
      state.lastNotify.left = state.lineNums.left;
    }
    if (state.lineNums.right - state.lastNotify.right) {
      this._notifyRange(
          state.lastNotify.right,
          state.lineNums.right,
          'right');
      state.lastNotify.right = state.lineNums.right;
    }
  }

  _notifyRange(start, end, side) {
    for (const fn of this._listeners) {
      fn(start, end, side);
    }
  }

  _loadHLJS() {
    return this.$.libLoader.getHLJS().then(hljs => {
      this._hljs = hljs;
    });
  }
}

customElements.define(GrSyntaxLayer.is, GrSyntaxLayer);
