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

const basicFixture = fixtureFromElement('gr-syntax-layer');

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 = basicFixture.instantiate();
    diff = getMockDiffResponse();
    element.diff = diff;
  });

  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();
    const highlightSpy = sinon.spy(mockHLJS, 'highlight');
    sinon.stub(element.libLoader, 'getHLJS').callsFake(
        () => Promise.resolve(mockHLJS));
    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('_diffChanged calls cancel', () => {
    const cancelSpy = sinon.spy(element, '_diffChanged');
    element.diff = {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);
  });
});

