/**
 * @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 '../../../test/common-test-setup-karma.js';
import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
import './gr-syntax-layer.js';
import {GrAnnotation} from '../gr-diff-highlight/gr-annotation.js';
import {GrDiffLine, GrDiffLineType} from '../gr-diff/gr-diff-line.js';
import {GrSyntaxLayer} from './gr-syntax-layer.js';

suite('gr-syntax-layer tests', () => {
  let diff;
  let element;
  const lineNumberEl = document.createElement('td');

  function getMockHLJS() {
    const html = '<span class="gr-diff gr-syntax gr-syntax-string">' +
        'ipsum</span>';
    return {
      configure() {},
      highlight(lang, line, ignore, state) {
        return {
          value: line.replace(/ipsum/, html),
          top: state === undefined ? 1 : state + 1,
        };
      },
      // Return something truthy because this method is used to check if the
      // language is supported.
      getLanguage(s) {
        return {};
      },
    };
  }

  setup(() => {
    element = new GrSyntaxLayer();
    diff = getMockDiffResponse();
    element.diff = diff;
  });

  teardown(() => {
    if (window.hljs) {
      delete window.hljs;
    }
  });

  test('annotate without range does nothing', () => {
    const annotationSpy = sinon.spy(GrAnnotation, 'annotateElement');
    const el = document.createElement('div');
    el.textContent = 'Etiam dui, blandit wisi.';
    const line = new GrDiffLine(GrDiffLineType.REMOVE);
    line.beforeNumber = 12;

    element.annotate(el, lineNumberEl, line);

    assert.isFalse(annotationSpy.called);
  });

  test('annotate with range applies it', () => {
    const str = 'Etiam dui, blandit wisi.';
    const start = 6;
    const length = 3;
    const className = 'foobar';

    const annotationSpy = sinon.spy(GrAnnotation, 'annotateElement');
    const el = document.createElement('div');
    el.textContent = str;
    const line = new GrDiffLine(GrDiffLineType.REMOVE);
    line.beforeNumber = 12;
    element.baseRanges[11] = [{
      start,
      length,
      className,
    }];

    element.annotate(el, lineNumberEl, line);

    assert.isTrue(annotationSpy.called);
    assert.equal(annotationSpy.lastCall.args[0], el);
    assert.equal(annotationSpy.lastCall.args[1], start);
    assert.equal(annotationSpy.lastCall.args[2], length);
    assert.equal(annotationSpy.lastCall.args[3], className);
    assert.isOk(el.querySelector('hl.' + className));
  });

  test('annotate with range but disabled does nothing', () => {
    const str = 'Etiam dui, blandit wisi.';
    const start = 6;
    const length = 3;
    const className = 'foobar';

    const annotationSpy = sinon.spy(GrAnnotation, 'annotateElement');
    const el = document.createElement('div');
    el.textContent = str;
    const line = new GrDiffLine(GrDiffLineType.REMOVE);
    line.beforeNumber = 12;
    element.baseRanges[11] = [{
      start,
      length,
      className,
    }];
    element.enabled = false;

    element.annotate(el, lineNumberEl, line);

    assert.isFalse(annotationSpy.called);
  });

  test('process on empty diff does nothing', done => {
    element.diff = {
      meta_a: {content_type: 'application/json'},
      meta_b: {content_type: 'application/json'},
      content: [],
    };
    const processNextSpy = sinon.spy(element, '_processNextLine');

    const processPromise = element.process();

    processPromise.then(() => {
      assert.isFalse(processNextSpy.called);
      assert.equal(element.baseRanges.length, 0);
      assert.equal(element.revisionRanges.length, 0);
      done();
    });
  });

  test('process for unsupported languages does nothing', done => {
    element.diff = {
      meta_a: {content_type: 'text/x+objective-cobol-plus-plus'},
      meta_b: {content_type: 'application/not-a-real-language'},
      content: [],
    };
    const processNextSpy = sinon.spy(element, '_processNextLine');

    const processPromise = element.process();

    processPromise.then(() => {
      assert.isFalse(processNextSpy.called);
      assert.equal(element.baseRanges.length, 0);
      assert.equal(element.revisionRanges.length, 0);
      done();
    });
  });

  test('process while disabled does nothing', done => {
    const processNextSpy = sinon.spy(element, '_processNextLine');
    element.enabled = false;
    const loadHLJSSpy = sinon.spy(element, '_loadHLJS');

    const processPromise = element.process();

    processPromise.then(() => {
      assert.isFalse(processNextSpy.called);
      assert.equal(element.baseRanges.length, 0);
      assert.equal(element.revisionRanges.length, 0);
      assert.isFalse(loadHLJSSpy.called);
      done();
    });
  });

  test('process highlight ipsum', done => {
    element.diff.meta_a.content_type = 'application/json';
    element.diff.meta_b.content_type = 'application/json';

    const mockHLJS = getMockHLJS();
    window.hljs = mockHLJS;
    const highlightSpy = sinon.spy(mockHLJS, 'highlight');
    const processNextSpy = sinon.spy(element, '_processNextLine');
    const processPromise = element.process();

    processPromise.then(() => {
      const linesA = diff.meta_a.lines;
      const linesB = diff.meta_b.lines;

      assert.isTrue(processNextSpy.called);
      assert.equal(element.baseRanges.length, linesA);
      assert.equal(element.revisionRanges.length, linesB);

      assert.equal(highlightSpy.callCount, linesA + linesB);

      // The first line of both sides have a range.
      let ranges = [element.baseRanges[0], element.revisionRanges[0]];
      for (const range of ranges) {
        assert.equal(range.length, 1);
        assert.equal(range[0].className,
            'gr-diff gr-syntax gr-syntax-string');
        assert.equal(range[0].start, 'lorem '.length);
        assert.equal(range[0].length, 'ipsum'.length);
      }

      // There are no ranges from ll.1-12 on the left and ll.1-11 on the
      // right.
      ranges = element.baseRanges.slice(1, 12)
          .concat(element.revisionRanges.slice(1, 11));

      for (const range of ranges) {
        assert.equal(range.length, 0);
      }

      // There should be another pair of ranges on l.13 for the left and
      // l.12 for the right.
      ranges = [element.baseRanges[13], element.revisionRanges[12]];

      for (const range of ranges) {
        assert.equal(range.length, 1);
        assert.equal(range[0].className,
            'gr-diff gr-syntax gr-syntax-string');
        assert.equal(range[0].start, 32);
        assert.equal(range[0].length, 'ipsum'.length);
      }

      // The next group should have a similar instance on either side.

      let range = element.baseRanges[15];
      assert.equal(range.length, 1);
      assert.equal(range[0].className, 'gr-diff gr-syntax gr-syntax-string');
      assert.equal(range[0].start, 34);
      assert.equal(range[0].length, 'ipsum'.length);

      range = element.revisionRanges[14];
      assert.equal(range.length, 1);
      assert.equal(range[0].className, 'gr-diff gr-syntax gr-syntax-string');
      assert.equal(range[0].start, 35);
      assert.equal(range[0].length, 'ipsum'.length);

      done();
    });
  });

  test('init calls cancel', () => {
    const cancelSpy = sinon.spy(element, 'cancel');
    element.init({content: []});
    assert.isTrue(cancelSpy.called);
  });

  test('_rangesFromElement no ranges', () => {
    const elem = document.createElement('span');
    elem.textContent = 'Etiam dui, blandit wisi.';
    const offset = 100;

    const result = element._rangesFromElement(elem, offset);

    assert.equal(result.length, 0);
  });

  test('_rangesFromElement single range', () => {
    const str0 = 'Etiam ';
    const str1 = 'dui, blandit';
    const str2 = ' wisi.';
    const className = 'gr-diff gr-syntax gr-syntax-string';
    const offset = 100;

    const elem = document.createElement('span');
    elem.appendChild(document.createTextNode(str0));
    const span = document.createElement('span');
    span.textContent = str1;
    span.className = className;
    elem.appendChild(span);
    elem.appendChild(document.createTextNode(str2));

    const result = element._rangesFromElement(elem, offset);

    assert.equal(result.length, 1);
    assert.equal(result[0].start, str0.length + offset);
    assert.equal(result[0].length, str1.length);
    assert.equal(result[0].className, className);
  });

  test('_rangesFromElement non-allowed', () => {
    const str0 = 'Etiam ';
    const str1 = 'dui, blandit';
    const str2 = ' wisi.';
    const className = 'not-in-the-safelist';
    const offset = 100;

    const elem = document.createElement('span');
    elem.appendChild(document.createTextNode(str0));
    const span = document.createElement('span');
    span.textContent = str1;
    span.className = className;
    elem.appendChild(span);
    elem.appendChild(document.createTextNode(str2));

    const result = element._rangesFromElement(elem, offset);

    assert.equal(result.length, 0);
  });

  test('_rangesFromElement milti range', () => {
    const str0 = 'Etiam ';
    const str1 = 'dui,';
    const str2 = ' blandit';
    const str3 = ' wisi.';
    const className = 'gr-diff gr-syntax gr-syntax-string';
    const offset = 100;

    const elem = document.createElement('span');
    elem.appendChild(document.createTextNode(str0));
    let span = document.createElement('span');
    span.textContent = str1;
    span.className = className;
    elem.appendChild(span);
    elem.appendChild(document.createTextNode(str2));
    span = document.createElement('span');
    span.textContent = str3;
    span.className = className;
    elem.appendChild(span);

    const result = element._rangesFromElement(elem, offset);

    assert.equal(result.length, 2);

    assert.equal(result[0].start, str0.length + offset);
    assert.equal(result[0].length, str1.length);
    assert.equal(result[0].className, className);

    assert.equal(result[1].start,
        str0.length + str1.length + str2.length + offset);
    assert.equal(result[1].length, str3.length);
    assert.equal(result[1].className, className);
  });

  test('_rangesFromElement nested range', () => {
    const str0 = 'Etiam ';
    const str1 = 'dui,';
    const str2 = ' blandit';
    const str3 = ' wisi.';
    const className = 'gr-diff gr-syntax gr-syntax-string';
    const offset = 100;

    const elem = document.createElement('span');
    elem.appendChild(document.createTextNode(str0));
    const span1 = document.createElement('span');
    span1.textContent = str1;
    span1.className = className;
    elem.appendChild(span1);
    const span2 = document.createElement('span');
    span2.textContent = str2;
    span2.className = className;
    span1.appendChild(span2);
    elem.appendChild(document.createTextNode(str3));

    const result = element._rangesFromElement(elem, offset);

    assert.equal(result.length, 2);

    assert.equal(result[0].start, str0.length + offset);
    assert.equal(result[0].length, str1.length + str2.length);
    assert.equal(result[0].className, className);

    assert.equal(result[1].start, str0.length + str1.length + offset);
    assert.equal(result[1].length, str2.length);
    assert.equal(result[1].className, className);
  });

  test('_rangesFromString safelist allows recursion', () => {
    const str = [
      '<span class="non-whtelisted-class">',
      '<span class="gr-diff gr-syntax gr-syntax-keyword">public</span>',
      '</span>'].join('');
    const result = element._rangesFromString(str, new Map());
    assert.notEqual(result.length, 0);
  });

  test('_rangesFromString cache same syntax markers', () => {
    sinon.spy(element, '_rangesFromElement');
    const str =
      '<span class="gr-diff gr-syntax gr-syntax-keyword">public</span>';
    const cacheMap = new Map();
    element._rangesFromString(str, cacheMap);
    element._rangesFromString(str, cacheMap);
    assert.isTrue(element._rangesFromElement.calledOnce);
  });

  test('_isSectionDone', () => {
    let state = {sectionIndex: 0, lineIndex: 0};
    assert.isFalse(element._isSectionDone(state));

    state = {sectionIndex: 0, lineIndex: 2};
    assert.isFalse(element._isSectionDone(state));

    state = {sectionIndex: 0, lineIndex: 4};
    assert.isTrue(element._isSectionDone(state));

    state = {sectionIndex: 1, lineIndex: 2};
    assert.isFalse(element._isSectionDone(state));

    state = {sectionIndex: 1, lineIndex: 3};
    assert.isTrue(element._isSectionDone(state));

    state = {sectionIndex: 3, lineIndex: 0};
    assert.isFalse(element._isSectionDone(state));

    state = {sectionIndex: 3, lineIndex: 3};
    assert.isFalse(element._isSectionDone(state));

    state = {sectionIndex: 3, lineIndex: 4};
    assert.isTrue(element._isSectionDone(state));
  });

  test('workaround CPP LT directive', () => {
    // Does nothing to regular line.
    let line = 'int main(int argc, char** argv) { return 0; }';
    assert.equal(element._workaround('cpp', line), line);

    // Does nothing to include directive.
    line = '#include <stdio>';
    assert.equal(element._workaround('cpp', line), line);

    // Converts left-shift operator in #define.
    line = '#define GiB (1ull << 30)';
    let expected = '#define GiB (1ull || 30)';
    assert.equal(element._workaround('cpp', line), expected);

    // Converts less-than operator in #if.
    line = '  #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)';
    expected = '  #if __GNUC__ | 4 || (__GNUC__ == 4 && __GNUC_MINOR__ | 1)';
    assert.equal(element._workaround('cpp', line), expected);
  });

  test('workaround Java param-annotation', () => {
    // Does nothing to regular line.
    let line = 'public static void foo(int bar) { }';
    assert.equal(element._workaround('java', line), line);

    // Does nothing to regular annotation.
    line = 'public static void foo(@Nullable int bar) { }';
    assert.equal(element._workaround('java', line), line);

    // Converts parameterized annotation.
    line = 'public static void foo(@SuppressWarnings("unused") int bar) { }';
    const expected = 'public static void foo(@SuppressWarnings "unused" ' +
        ' int bar) { }';
    assert.equal(element._workaround('java', line), expected);
  });

  test('workaround CPP whcar_t character literals', () => {
    // Does nothing to regular line.
    let line = 'int main(int argc, char** argv) { return 0; }';
    assert.equal(element._workaround('cpp', line), line);

    // Does nothing to wchar_t string.
    line = 'wchar_t* sz = L"abc 123";';
    assert.equal(element._workaround('cpp', line), line);

    // Converts wchar_t character literal to string.
    line = 'wchar_t myChar = L\'#\'';
    let expected = 'wchar_t myChar = L"."';
    assert.equal(element._workaround('cpp', line), expected);

    // Converts wchar_t character literal with escape sequence to string.
    line = 'wchar_t myChar = L\'\\"\'';
    expected = 'wchar_t myChar = L"\\."';
    assert.equal(element._workaround('cpp', line), expected);
  });

  test('workaround go backslash character literals', () => {
    // Does nothing to regular line.
    let line = 'func foo(in []byte) (lit []byte, n int, err error) {';
    assert.equal(element._workaround('go', line), line);

    // Does nothing to string with backslash literal
    line = 'c := "\\\\"';
    assert.equal(element._workaround('go', line), line);

    // Converts backslash literal character to a string.
    line = 'c := \'\\\\\'';
    const expected = 'c := "\\\\"';
    assert.equal(element._workaround('go', line), expected);
  });
});

