/**
 * @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.
 */
(function() {
  'use strict';

  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-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-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;

  class GrSyntaxLayer extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    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(() => {
            return 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);
})();
