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

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