/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-diff-selection';
import {GrDiffSelection} from './gr-diff-selection';
import {createDiff} from '../../../test/test-data-generators';
import {DiffInfo, Side} from '../../../api/diff';
import {GrFormattedText} from '../../../elements/shared/gr-formatted-text/gr-formatted-text';
import {fixture, html, assert} from '@open-wc/testing';
import {mouseDown} from '../../../test/test-utils';

const diffTableTemplate = html`
  <table id="diffTable" class="side-by-side">
    <tr class="diff-row">
      <td class="blame" data-line-number="1"></td>
      <td class="lineNum left" data-value="1">1</td>
      <td class="content">
        <div class="contentText" data-side="left">ba ba</div>
        <div data-side="left">
          <div class="comment-thread">
            <div class="gr-formatted-text message">
              <span id="output" class="gr-markdown">This is a comment</span>
            </div>
          </div>
        </div>
      </td>
      <td class="lineNum right" data-value="1">1</td>
      <td class="content">
        <div class="contentText" data-side="right">some other text</div>
      </td>
    </tr>
    <tr class="diff-row">
      <td class="blame" data-line-number="2"></td>
      <td class="lineNum left" data-value="2">2</td>
      <td class="content">
        <div class="contentText" data-side="left">zin</div>
      </td>
      <td class="lineNum right" data-value="2">2</td>
      <td class="content">
        <div class="contentText" data-side="right">more more more</div>
        <div data-side="right">
          <div class="comment-thread">
            <div class="gr-formatted-text message">
              <span id="output" class="gr-markdown"
                >This is a comment on the right</span
              >
            </div>
          </div>
        </div>
      </td>
    </tr>
    <tr class="diff-row">
      <td class="blame" data-line-number="3"></td>
      <td class="lineNum left" data-value="3">3</td>
      <td class="content">
        <div class="contentText" data-side="left">ga ga</div>
        <div data-side="left">
          <div class="comment-thread">
            <div class="gr-formatted-text message">
              <span id="output" class="gr-markdown"
                >This is <a>a</a> different comment 💩 unicode is fun</span
              >
            </div>
          </div>
        </div>
      </td>
      <td class="lineNum right" data-value="3">3</td>
    </tr>
    <tr class="diff-row">
      <td class="blame" data-line-number="4"></td>
      <td class="lineNum left" data-value="4">4</td>
      <td class="content">
        <div class="contentText" data-side="left">ga ga</div>
        <div data-side="left">
          <div class="comment-thread">
            <textarea data-side="right">test for textarea copying</textarea>
          </div>
        </div>
      </td>
      <td class="lineNum right" data-value="4">4</td>
    </tr>
    <tr class="not-diff-row">
      <td class="other">
        <div class="contentText" data-side="right">some other text</div>
      </td>
    </tr>
  </table>
`;

suite('gr-diff-selection', () => {
  let element: GrDiffSelection;
  let diffTable: HTMLTableElement;

  const emulateCopyOn = function (target: HTMLElement | null) {
    const fakeEvent = {
      target,
      preventDefault: sinon.stub(),
      composedPath() {
        return [target];
      },
      clipboardData: {
        setData: sinon.stub(),
      },
    };
    element.handleCopy(fakeEvent as unknown as ClipboardEvent);
    return fakeEvent;
  };

  setup(async () => {
    element = new GrDiffSelection();
    diffTable = await fixture<HTMLTableElement>(diffTableTemplate);

    const diff: DiffInfo = {
      ...createDiff(),
      content: [
        {
          a: ['ba ba'],
          b: ['some other text'],
        },
        {
          a: ['zin'],
          b: ['more more more'],
        },
        {
          a: ['ga ga'],
          b: ['some other text'],
        },
      ],
    };
    element.init(diff, diffTable);
  });

  test('applies selected-left on left side click', () => {
    element.diffTable!.classList.add('selected-right');
    const lineNumberEl = diffTable.querySelector<HTMLElement>('.lineNum.left');
    if (!lineNumberEl) assert.fail('line number element missing');
    mouseDown(lineNumberEl);
    assert.isTrue(
      element.diffTable!.classList.contains('selected-left'),
      'adds selected-left'
    );
    assert.isFalse(
      element.diffTable!.classList.contains('selected-right'),
      'removes selected-right'
    );
  });

  test('applies selected-right on right side click', () => {
    element.diffTable!.classList.add('selected-left');
    const lineNumberEl = diffTable.querySelector<HTMLElement>('.lineNum.right');
    if (!lineNumberEl) assert.fail('line number element missing');
    mouseDown(lineNumberEl);
    assert.isTrue(
      element.diffTable!.classList.contains('selected-right'),
      'adds selected-right'
    );
    assert.isFalse(
      element.diffTable!.classList.contains('selected-left'),
      'removes selected-left'
    );
  });

  test('applies selected-blame on blame click', () => {
    element.diffTable!.classList.add('selected-left');
    const blameDiv = document.createElement('div');
    blameDiv.classList.add('blame');
    element.diffTable!.appendChild(blameDiv);
    mouseDown(blameDiv);
    assert.isTrue(
      element.diffTable!.classList.contains('selected-blame'),
      'adds selected-right'
    );
    assert.isFalse(
      element.diffTable!.classList.contains('selected-left'),
      'removes selected-left'
    );
  });

  test('ignores copy for non-content Element', () => {
    const getSelectedTextStub = sinon.stub(element, 'getSelectedText');
    emulateCopyOn(diffTable.querySelector('.not-diff-row'));
    assert.isFalse(getSelectedTextStub.called);
  });

  test('asks for text for left side Elements', () => {
    const getSelectedTextStub = sinon.stub(element, 'getSelectedText');
    emulateCopyOn(diffTable.querySelector('div.contentText'));
    assert.deepEqual([Side.LEFT, false], getSelectedTextStub.lastCall.args);
  });

  test('reacts to copy for content Elements', () => {
    const getSelectedTextStub = sinon.stub(element, 'getSelectedText');
    emulateCopyOn(diffTable.querySelector('div.contentText'));
    assert.isTrue(getSelectedTextStub.called);
  });

  test('copy event is prevented for content Elements', () => {
    const getSelectedTextStub = sinon.stub(element, 'getSelectedText');
    getSelectedTextStub.returns('test');
    const event = emulateCopyOn(diffTable.querySelector('div.contentText'));
    assert.isTrue(event.preventDefault.called);
  });

  test('inserts text into clipboard on copy', () => {
    sinon.stub(element, 'getSelectedText').returns('the text');
    const event = emulateCopyOn(diffTable.querySelector('div.contentText'));
    assert.deepEqual(
      ['Text', 'the text'],
      event.clipboardData.setData.lastCall.args
    );
  });

  test('setClasses adds given SelectionClass values, removes others', () => {
    element.diffTable!.classList.add('selected-right');
    element.setClasses(['selected-comment', 'selected-left']);
    assert.isTrue(element.diffTable!.classList.contains('selected-comment'));
    assert.isTrue(element.diffTable!.classList.contains('selected-left'));
    assert.isFalse(element.diffTable!.classList.contains('selected-right'));
    assert.isFalse(element.diffTable!.classList.contains('selected-blame'));

    element.setClasses(['selected-blame']);
    assert.isFalse(element.diffTable!.classList.contains('selected-comment'));
    assert.isFalse(element.diffTable!.classList.contains('selected-left'));
    assert.isFalse(element.diffTable!.classList.contains('selected-right'));
    assert.isTrue(element.diffTable!.classList.contains('selected-blame'));
  });

  test('setClasses removes before it ads', () => {
    element.diffTable!.classList.add('selected-right');
    const addStub = sinon.stub(element.diffTable!.classList, 'add');
    const removeStub = sinon
      .stub(element.diffTable!.classList, 'remove')
      .callsFake(() => {
        assert.isFalse(addStub.called);
      });
    element.setClasses(['selected-comment', 'selected-left']);
    assert.isTrue(addStub.called);
    assert.isTrue(removeStub.called);
  });

  test('copies content correctly', () => {
    element.diffTable!.classList.add('selected-left');
    element.diffTable!.classList.remove('selected-right');

    const selection = document.getSelection();
    if (selection === null) assert.fail('no selection');
    selection.removeAllRanges();
    const range = document.createRange();
    range.setStart(diffTable.querySelector('div.contentText')!.firstChild!, 3);
    range.setEnd(
      diffTable.querySelectorAll('div.contentText')[4]!.firstChild!,
      2
    );
    selection.addRange(range);
    assert.equal(element.getSelectedText(Side.LEFT, false), 'ba\nzin\nga');
  });

  test('copies comments', () => {
    element.diffTable!.classList.add('selected-left');
    element.diffTable!.classList.add('selected-comment');
    element.diffTable!.classList.remove('selected-right');
    const selection = document.getSelection();
    if (selection === null) assert.fail('no selection');
    selection.removeAllRanges();
    const range = document.createRange();
    range.setStart(
      diffTable.querySelector('.gr-formatted-text *')!.firstChild!,
      3
    );
    range.setEnd(
      diffTable.querySelectorAll('.gr-formatted-text *')[2].childNodes[2],
      7
    );
    selection.addRange(range);
    assert.equal(
      's is a comment\nThis is a differ',
      element.getSelectedText(Side.LEFT, true)
    );
  });

  test('respects astral chars in comments', () => {
    element.diffTable!.classList.add('selected-left');
    element.diffTable!.classList.add('selected-comment');
    element.diffTable!.classList.remove('selected-right');
    const selection = document.getSelection();
    if (selection === null) assert.fail('no selection');
    selection.removeAllRanges();
    const range = document.createRange();
    const nodes = diffTable.querySelectorAll('.gr-formatted-text *');
    range.setStart(nodes[2].childNodes[2], 13);
    range.setEnd(nodes[2].childNodes[2], 23);
    selection.addRange(range);
    assert.equal('mment 💩 u', element.getSelectedText(Side.LEFT, true));
  });

  test('defers to default behavior for textarea', () => {
    element.diffTable!.classList.add('selected-left');
    element.diffTable!.classList.remove('selected-right');
    const selectedTextSpy = sinon.spy(element, 'getSelectedText');
    emulateCopyOn(diffTable.querySelector('textarea'));
    assert.isFalse(selectedTextSpy.called);
  });

  test('regression test for 4794', () => {
    element.diffTable!.classList.add('selected-right');
    element.diffTable!.classList.remove('selected-left');

    const selection = document.getSelection();
    if (!selection) assert.fail('no selection');
    selection.removeAllRanges();
    const range = document.createRange();
    range.setStart(
      diffTable.querySelectorAll('div.contentText')[1]!.firstChild!,
      4
    );
    range.setEnd(
      diffTable.querySelectorAll('div.contentText')[1]!.firstChild!,
      10
    );
    selection.addRange(range);
    assert.equal(element.getSelectedText(Side.RIGHT, false), ' other');
  });

  test('copies to end of side (issue 7895)', () => {
    element.diffTable!.classList.add('selected-left');
    element.diffTable!.classList.remove('selected-right');
    const selection = document.getSelection();
    if (selection === null) assert.fail('no selection');
    selection.removeAllRanges();
    const range = document.createRange();
    range.setStart(diffTable.querySelector('div.contentText')!.firstChild!, 3);
    range.setEnd(
      diffTable.querySelectorAll('div.contentText')[4]!.firstChild!,
      2
    );
    selection.addRange(range);
    assert.equal(element.getSelectedText(Side.LEFT, false), 'ba\nzin\nga');
  });

  suite('getTextContentForRange', () => {
    let selection: Selection;
    let range: Range;
    let nodes: NodeListOf<GrFormattedText>;

    setup(() => {
      element.diffTable!.classList.add('selected-left');
      element.diffTable!.classList.add('selected-comment');
      element.diffTable!.classList.remove('selected-right');
      const s = document.getSelection();
      if (s === null) assert.fail('no selection');
      selection = s;
      selection.removeAllRanges();
      range = document.createRange();
      nodes = diffTable.querySelectorAll('.gr-formatted-text *');
    });

    test('multi level element contained in range', () => {
      range.setStart(nodes[2].childNodes[0], 1);
      range.setEnd(nodes[2].childNodes[2], 7);
      selection.addRange(range);
      assert.equal(
        element.getTextContentForRange(diffTable, selection, range),
        'his is a differ'
      );
    });

    test('multi level element as startContainer of range', () => {
      range.setStart(nodes[2].childNodes[1], 0);
      range.setEnd(nodes[2].childNodes[2], 7);
      selection.addRange(range);
      assert.equal(
        element.getTextContentForRange(diffTable, selection, range),
        'a differ'
      );
    });

    test('startContainer === endContainer', () => {
      range.setStart(nodes[0].firstChild!, 2);
      range.setEnd(nodes[0].firstChild!, 12);
      selection.addRange(range);
      assert.equal(
        element.getTextContentForRange(diffTable, selection, range),
        'is is a co'
      );
    });
  });
});
