/**
 * @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} 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(GrDiffLine.Type.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(GrDiffLine.Type.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(GrDiffLine.Type.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);
  });
});

