/**
 * @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-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;

  Polymer({
    is: 'gr-syntax-layer',
    _legacyUndefinedCheck: true,

    properties: {
      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);
    },

    /**
     * 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 symtax 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},
      };

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

                // 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.
     * @return {!Array<!Object>} The list of ranges.
     */
    _rangesFromString(str) {
      const div = document.createElement('div');
      div.innerHTML = str;
      return this._rangesFromElement(div, 0);
    },

    _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) {
      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));
        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));
        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;
      });
    },
  });
})();
