/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-diff-host';
import {
  CommentSide,
  createDefaultDiffPrefs,
  Side,
} from '../../../constants/constants';
import {
  createAccountDetailWithId,
  createBlame,
  createChange,
  createComment,
  createCommentThread,
  createDiff,
  createPatchRange,
  createRunResult,
} from '../../../test/test-data-generators';
import {
  addListenerForTest,
  mockPromise,
  query,
  queryAll,
  queryAndAssert,
  stubReporting,
  stubRestApi,
} from '../../../test/test-utils';
import {
  BasePatchSetNum,
  BlameInfo,
  CommentRange,
  CommentThread,
  DraftInfo,
  EDIT,
  ImageInfo,
  NumericChangeId,
  PARENT,
  PatchSetNum,
  RevisionPatchSetNum,
} from '../../../types/common';
import {CoverageType} from '../../../types/types';
import {GrDiffHost} from './gr-diff-host';
import {DiffInfo, DiffViewMode, IgnoreWhitespaceType} from '../../../api/diff';
import {ErrorCallback} from '../../../api/rest';
import {SinonStub, SinonStubbedMember} from 'sinon';
import {RunResult} from '../../../models/checks/checks-model';
import {assertIsDefined} from '../../../utils/common-util';
import {fixture, html, assert} from '@open-wc/testing';
import {testResolver} from '../../../test/common-test-setup';
import {userModelToken, UserModel} from '../../../models/user/user-model';
import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {ReportingService} from '../../../services/gr-reporting/gr-reporting';
import {RestApiService} from '../../../services/gr-rest-api/gr-rest-api';
import {
  CommentsModel,
  commentsModelToken,
} from '../../../models/comments/comments-model';
import {isNewDiff} from '../../../embed/diff/gr-diff/gr-diff-utils';

suite('gr-diff-host tests', () => {
  let element: GrDiffHost;
  let account = createAccountDetailWithId(1);
  let getDiffRestApiStub: SinonStubbedMember<RestApiService['getDiff']>;
  let userModel: UserModel;

  setup(async () => {
    stubRestApi('getAccount').callsFake(() => Promise.resolve(account));
    element = await fixture(html`<gr-diff-host></gr-diff-host>`);
    element.changeNum = 123 as NumericChangeId;
    element.path = 'some/path';
    element.change = createChange();
    element.patchRange = createPatchRange();
    getDiffRestApiStub = stubRestApi('getDiff');
    // Fall back in case a test forgets to set one up
    getDiffRestApiStub.returns(Promise.resolve(createDiff()));
    await element.updateComplete;
    userModel = testResolver(userModelToken);
  });

  suite('render reporting', () => {
    test('ends total and syntax timer after syntax layer', async () => {
      const displayedStub = stubReporting('diffViewContentDisplayed');

      element.patchRange = createPatchRange();
      element.change = createChange();
      element.prefs = createDefaultDiffPrefs();
      await element.updateComplete;
      // Force a reload because it's not possible to wait on the reload called
      // from update().
      await element.reload();
      const timeEndStub = sinon.stub(element.reporting, 'timeEnd');
      let notifySyntaxProcessed: () => void = () => {};
      sinon.stub(element.syntaxLayer, 'process').returns(
        new Promise(resolve => {
          notifySyntaxProcessed = resolve;
        })
      );
      const promise = element.reload(true);
      // Multiple cascading microtasks are scheduled.
      notifySyntaxProcessed();
      await element.updateComplete;
      await promise;
      const calls = timeEndStub.getCalls();
      assert.equal(calls.length, 4);
      assert.equal(calls[0].args[0], 'Diff Load Render');
      assert.equal(calls[1].args[0], 'Diff Content Render');
      assert.equal(calls[2].args[0], 'Diff Syntax Render');
      assert.equal(calls[3].args[0], 'Diff Total Render');
      assert.isTrue(displayedStub.called);
    });

    test('completes reload promise after syntax layer processing', async () => {
      let notifySyntaxProcessed: () => void = () => {};
      sinon.stub(element.syntaxLayer, 'process').returns(
        new Promise(resolve => {
          notifySyntaxProcessed = resolve;
        })
      );
      getDiffRestApiStub.returns(Promise.resolve(createDiff()));
      element.patchRange = createPatchRange();
      element.change = createChange();
      let reloadComplete = false;
      element.prefs = createDefaultDiffPrefs();
      const promise = mockPromise();
      element.reload().then(() => {
        reloadComplete = true;
        promise.resolve();
      });
      // Multiple cascading microtasks are scheduled.
      assert.isFalse(reloadComplete);
      notifySyntaxProcessed();
      await promise;
      assert.isTrue(reloadComplete);
    });
  });

  test('render', () => {
    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <gr-diff
          id="diff"
          style="--line-limit-marker:-1px; --content-width:100ch; --diff-max-width:none; --font-size:12px;"
        >
        </gr-diff>
      `,
      {ignoreAttributes: ['style']}
    );
  });

  test('reload() cancels before network resolves', async () => {
    if (isNewDiff()) return;
    assertIsDefined(element.diffElement);
    const cancelStub = sinon.stub(element.diffElement, 'cancel');

    // Stub the network calls into requests that never resolve.
    sinon.stub(element, 'getDiff').callsFake(() => new Promise(() => {}));
    element.patchRange = createPatchRange();
    element.change = createChange();
    element.prefs = undefined;

    // Needs to be set to something first for it to cancel.
    element.diff = createDiff();
    await element.updateComplete;

    element.reload();
    assert.isTrue(cancelStub.called);
  });

  test('prefetch getDiff', async () => {
    getDiffRestApiStub.returns(Promise.resolve(createDiff()));
    element.changeNum = 123 as NumericChangeId;
    element.patchRange = createPatchRange();
    element.path = 'file.txt';
    element.prefetchDiff();
    await element.getDiff();
    assert.isTrue(getDiffRestApiStub.calledOnce);
  });

  test('getDiff handles undefined diff responses', async () => {
    getDiffRestApiStub.returns(Promise.resolve(undefined));
    element.changeNum = 123 as NumericChangeId;
    element.patchRange = createPatchRange();
    element.path = 'file.txt';
    await element.getDiff();
  });

  test('reload resolves on error', () => {
    const onErrStub = sinon.stub(element, 'handleGetDiffError');
    const error = new Response(null, {status: 500});
    getDiffRestApiStub.callsFake(
      (
        _1: NumericChangeId,
        _2: PatchSetNum,
        _3: PatchSetNum,
        _4: string,
        _5?: IgnoreWhitespaceType,
        onErr?: ErrorCallback
      ) => {
        if (onErr) onErr(error);
        return Promise.resolve(undefined);
      }
    );
    element.patchRange = createPatchRange();
    return element.reload().then(() => {
      assert.isTrue(onErrStub.calledOnce);
    });
  });

  suite('handleGetDiffError', () => {
    let serverErrorStub: sinon.SinonStub;
    let pageErrorStub: sinon.SinonStub;

    setup(() => {
      serverErrorStub = sinon.stub();
      addListenerForTest(document, 'server-error', serverErrorStub);
      pageErrorStub = sinon.stub();
      addListenerForTest(document, 'page-error', pageErrorStub);
    });

    test('page error on HTTP-409', () => {
      element.handleGetDiffError({status: 409} as Response);
      assert.isTrue(serverErrorStub.calledOnce);
      assert.isFalse(pageErrorStub.called);
      assert.isNotOk(element.errorMessage);
    });

    test('server error on non-HTTP-409', () => {
      element.handleGetDiffError({
        status: 500,
        text: () => Promise.resolve(''),
      } as Response);
      assert.isFalse(serverErrorStub.called);
      assert.isTrue(pageErrorStub.calledOnce);
      assert.isNotOk(element.errorMessage);
    });

    test('error message if showLoadFailure', () => {
      element.showLoadFailure = true;
      element.handleGetDiffError({
        status: 500,
        statusText: 'Failure!',
      } as Response);
      assert.isFalse(serverErrorStub.called);
      assert.isFalse(pageErrorStub.called);
      assert.equal(
        element.errorMessage,
        'Encountered error when loading the diff: 500 Failure!'
      );
    });
  });

  suite('image diffs', () => {
    let mockFile1: ImageInfo;
    let mockFile2: ImageInfo;
    setup(() => {
      mockFile1 = {
        body:
          'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAAAAAA/w==',
        type: 'image/bmp',
        _expectedType: 'image/bmp',
        _name: 'carrot.bmp',
      };
      mockFile2 = {
        body:
          'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAA/////w==',
        type: 'image/bmp',
        _expectedType: 'image/bmp',
        _name: 'potato.bmp',
      };

      element.patchRange = createPatchRange();
      element.change = createChange();
    });

    test('renders image diffs with same file name', async () => {
      const mockDiff: DiffInfo = {
        meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
        meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 560},
        intraline_status: 'OK',
        change_type: 'MODIFIED',
        diff_header: [
          'diff --git a/carrot.jpg b/carrot.jpg',
          'index 2adc47d..f9c2f2c 100644',
          '--- a/carrot.jpg',
          '+++ b/carrot.jpg',
          'Binary files differ',
        ],
        content: [{skip: 66}],
        binary: true,
      };
      getDiffRestApiStub.returns(Promise.resolve(mockDiff));
      stubRestApi('getImagesForDiff').returns(
        Promise.resolve({
          baseImage: {
            ...mockFile1,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
          revisionImage: {
            ...mockFile2,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
        })
      );

      element.prefs = createDefaultDiffPrefs();
      element.reload();
      await element.waitForReloadToRender();

      // Recognizes that it should be an image diff.
      assert.isTrue(element.isImageDiff);

      // Left image rendered with the parent commit's version of the file.
      assertIsDefined(element.diffElement);
      const leftImage = queryAndAssert(element.diffElement, 'td.left img');
      const leftLabel = queryAndAssert(element.diffElement, 'td.left label');
      const leftLabelContent = leftLabel.querySelector('.label');
      const leftLabelName = leftLabel.querySelector('.name');

      const rightImage = queryAndAssert(element.diffElement, 'td.right img');
      const rightLabel = queryAndAssert(element.diffElement, 'td.right label');
      const rightLabelContent = rightLabel.querySelector('.label');
      const rightLabelName = rightLabel.querySelector('.name');

      assert.isOk(leftImage);
      assert.equal(
        leftImage.getAttribute('src'),
        'data:image/bmp;base64,' + mockFile1.body
      );
      assert.isTrue(leftLabelContent?.textContent?.includes('image/bmp'));
      assert.isNotOk(leftLabelName);

      assert.isOk(rightImage);
      assert.equal(
        rightImage.getAttribute('src'),
        'data:image/bmp;base64,' + mockFile2.body
      );
      assert.isTrue(rightLabelContent?.textContent?.includes('image/bmp'));
      assert.isNotOk(rightLabelName);
    });

    test('renders image diffs with a different file name', async () => {
      const mockDiff: DiffInfo = {
        meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
        meta_b: {name: 'carrot2.jpg', content_type: 'image/jpeg', lines: 560},
        intraline_status: 'OK',
        change_type: 'MODIFIED',
        diff_header: [
          'diff --git a/carrot.jpg b/carrot2.jpg',
          'index 2adc47d..f9c2f2c 100644',
          '--- a/carrot.jpg',
          '+++ b/carrot2.jpg',
          'Binary files differ',
        ],
        content: [{skip: 66}],
        binary: true,
      };
      getDiffRestApiStub.returns(Promise.resolve(mockDiff));
      stubRestApi('getImagesForDiff').returns(
        Promise.resolve({
          baseImage: {
            ...mockFile1,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
          revisionImage: {
            ...mockFile2,
            _expectedType: 'image/jpeg',
            _name: 'carrot2.jpg',
          },
        })
      );

      element.prefs = createDefaultDiffPrefs();
      element.reload();
      await element.waitForReloadToRender();

      // Recognizes that it should be an image diff.
      assert.isTrue(element.isImageDiff);
      assertIsDefined(element.diffElement);

      // Left image rendered with the parent commit's version of the file.
      const leftImage = queryAndAssert(element.diffElement, 'td.left img');
      const leftLabel = queryAndAssert(element.diffElement, 'td.left label');
      const leftLabelContent = leftLabel.querySelector('.label');
      const leftLabelName = leftLabel.querySelector('.name');

      const rightImage = queryAndAssert(element.diffElement, 'td.right img');
      const rightLabel = queryAndAssert(element.diffElement, 'td.right label');
      const rightLabelContent = rightLabel.querySelector('.label');
      const rightLabelName = rightLabel.querySelector('.name');

      assert.isOk(rightLabelName);
      assert.isOk(leftLabelName);
      assert.equal(leftLabelName?.textContent, mockDiff.meta_a?.name);
      assert.equal(rightLabelName?.textContent, mockDiff.meta_b?.name);

      assert.isOk(leftImage);
      assert.equal(
        leftImage.getAttribute('src'),
        'data:image/bmp;base64,' + mockFile1.body
      );
      assert.isTrue(leftLabelContent?.textContent?.includes('image/bmp'));

      assert.isOk(rightImage);
      assert.equal(
        rightImage.getAttribute('src'),
        'data:image/bmp;base64,' + mockFile2.body
      );
      assert.isTrue(rightLabelContent?.textContent?.includes('image/bmp'));
    });

    test('renders added image', async () => {
      const mockDiff: DiffInfo = {
        meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 560},
        intraline_status: 'OK',
        change_type: 'ADDED',
        diff_header: [
          'diff --git a/carrot.jpg b/carrot.jpg',
          'index 0000000..f9c2f2c 100644',
          '--- /dev/null',
          '+++ b/carrot.jpg',
          'Binary files differ',
        ],
        content: [{skip: 66}],
        binary: true,
      };
      getDiffRestApiStub.returns(Promise.resolve(mockDiff));
      stubRestApi('getImagesForDiff').returns(
        Promise.resolve({
          baseImage: null,
          revisionImage: {
            ...mockFile2,
            _expectedType: 'image/jpeg',
            _name: 'carrot2.jpg',
          },
        })
      );

      element.prefs = createDefaultDiffPrefs();
      element.reload();
      await element.waitForReloadToRender().then(() => {
        // Recognizes that it should be an image diff.
        assert.isTrue(element.isImageDiff);
        assertIsDefined(element.diffElement);
        const leftImage = query(element.diffElement, 'td.left img');
        const rightImage = queryAndAssert(element.diffElement, 'td.right img');

        assert.isNotOk(leftImage);
        assert.isOk(rightImage);
      });
    });

    test('renders removed image', async () => {
      const mockDiff: DiffInfo = {
        meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 560},
        intraline_status: 'OK',
        change_type: 'DELETED',
        diff_header: [
          'diff --git a/carrot.jpg b/carrot.jpg',
          'index f9c2f2c..0000000 100644',
          '--- a/carrot.jpg',
          '+++ /dev/null',
          'Binary files differ',
        ],
        content: [{skip: 66}],
        binary: true,
      };
      getDiffRestApiStub.returns(Promise.resolve(mockDiff));
      stubRestApi('getImagesForDiff').returns(
        Promise.resolve({
          baseImage: {
            ...mockFile1,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
          revisionImage: null,
        })
      );

      element.prefs = createDefaultDiffPrefs();
      element.reload();
      await element.waitForReloadToRender().then(() => {
        // Recognizes that it should be an image diff.
        assert.isTrue(element.isImageDiff);
        assertIsDefined(element.diffElement);

        const leftImage = queryAndAssert(element.diffElement, 'td.left img');
        const rightImage = query(element.diffElement, 'td.right img');

        assert.isOk(leftImage);
        assert.isNotOk(rightImage);
      });
    });

    test('does not render disallowed image type', async () => {
      const mockDiff: DiffInfo = {
        meta_a: {
          name: 'carrot.jpg',
          content_type: 'image/jpeg-evil',
          lines: 560,
        },
        intraline_status: 'OK',
        change_type: 'DELETED',
        diff_header: [
          'diff --git a/carrot.jpg b/carrot.jpg',
          'index f9c2f2c..0000000 100644',
          '--- a/carrot.jpg',
          '+++ /dev/null',
          'Binary files differ',
        ],
        content: [{skip: 66}],
        binary: true,
      };
      mockFile1.type = 'image/jpeg-evil';

      getDiffRestApiStub.returns(Promise.resolve(mockDiff));
      stubRestApi('getImagesForDiff').returns(
        Promise.resolve({
          baseImage: {
            ...mockFile1,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
          revisionImage: null,
        })
      );

      element.prefs = createDefaultDiffPrefs();
      element.updateComplete.then(() => {
        // Recognizes that it should be an image diff.
        assert.isTrue(element.isImageDiff);
        assertIsDefined(element.diffElement);
        const leftImage = query(element.diffElement, 'td.left img');
        assert.isNotOk(leftImage);
      });
    });
  });

  test('cannot create comments when not logged in', () => {
    userModel.setAccount(undefined);
    element.patchRange = createPatchRange();
    const showAuthRequireSpy = sinon.spy();
    element.addEventListener('show-auth-required', showAuthRequireSpy);

    element.dispatchEvent(
      new CustomEvent('create-comment', {
        detail: {
          lineNum: 3,
          side: Side.LEFT,
          path: '/p',
        },
      })
    );

    assertIsDefined(element.diffElement);
    const threads = queryAll(element.diffElement, 'gr-comment-thread');
    assert.equal(threads.length, 0);
    assert.isTrue(showAuthRequireSpy.called);
  });

  test('delegates cancel()', () => {
    assertIsDefined(element.diffElement);
    const stub = sinon.stub(element.diffElement, 'cancel');
    element.patchRange = createPatchRange();
    element.cancel();
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  test('delegates getCursorStops()', () => {
    const returnValue = [document.createElement('b')];
    assertIsDefined(element.diffElement);
    const stub = sinon
      .stub(element.diffElement, 'getCursorStops')
      .returns(returnValue);
    assert.equal(element.getCursorStops(), returnValue);
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  test('delegates isRangeSelected()', () => {
    const returnValue = true;
    assertIsDefined(element.diffElement);
    const stub = sinon
      .stub(element.diffElement, 'isRangeSelected')
      .returns(returnValue);
    assert.equal(element.isRangeSelected(), returnValue);
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  test('delegates toggleLeftDiff()', () => {
    assertIsDefined(element.diffElement);
    const stub = sinon.stub(element.diffElement, 'toggleLeftDiff');
    element.toggleLeftDiff();
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  suite('blame', () => {
    setup(async () => {
      element = await fixture(html`<gr-diff-host></gr-diff-host>`);
      element.changeNum = 123 as NumericChangeId;
      element.path = 'some/path';
      await element.updateComplete;
    });

    test('clearBlame', async () => {
      element.blame = [];
      await element.updateComplete;
      assertIsDefined(element.diffElement);
      const isBlameLoadedStub = sinon.stub();
      element.addEventListener('is-blame-loaded-changed', isBlameLoadedStub);
      element.clearBlame();
      await element.updateComplete;
      assert.isNull(element.blame);
      assert.isTrue(isBlameLoadedStub.calledOnce);
      assert.isFalse(isBlameLoadedStub.args[0][0].detail.value);
    });

    test('loadBlame', async () => {
      const mockBlame: BlameInfo[] = [createBlame()];
      const showAlertStub = sinon.stub();
      element.addEventListener('show-alert', showAlertStub);
      const getBlameStub = stubRestApi('getBlame').returns(
        Promise.resolve(mockBlame)
      );
      const changeNum = 42 as NumericChangeId;
      element.changeNum = changeNum;
      element.patchRange = createPatchRange();
      element.path = 'foo/bar.baz';
      await element.updateComplete;
      const isBlameLoadedStub = sinon.stub();
      element.addEventListener('is-blame-loaded-changed', isBlameLoadedStub);

      return element.loadBlame().then(() => {
        assert.isTrue(
          getBlameStub.calledWithExactly(
            changeNum,
            1 as RevisionPatchSetNum,
            'foo/bar.baz',
            true
          )
        );
        assert.isFalse(showAlertStub.called);
        assert.equal(element.blame, mockBlame);
        assert.isTrue(isBlameLoadedStub.calledOnce);
        assert.isTrue(isBlameLoadedStub.args[0][0].detail.value);
      });
    });

    test('loadBlame empty', async () => {
      const mockBlame: BlameInfo[] = [];
      const showAlertStub = sinon.stub();
      const isBlameLoadedStub = sinon.stub();
      element.addEventListener('show-alert', showAlertStub);
      element.addEventListener('is-blame-loaded-changed', isBlameLoadedStub);
      stubRestApi('getBlame').returns(Promise.resolve(mockBlame));
      const changeNum = 42 as NumericChangeId;
      element.changeNum = changeNum;
      element.patchRange = createPatchRange();
      element.path = 'foo/bar.baz';
      await element.updateComplete;
      return element
        .loadBlame()
        .then(() => {
          assert.isTrue(false, 'Promise should not resolve');
        })
        .catch(() => {
          assert.isTrue(showAlertStub.calledOnce);
          assert.isNull(element.blame);
          // We don't expect a call because
          assert.isTrue(isBlameLoadedStub.notCalled);
        });
    });
  });

  test('delegates clearDiffContent()', () => {
    assertIsDefined(element.diffElement);
    const stub = sinon.stub(element.diffElement, 'clearDiffContent');
    element.clearDiffContent();
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  test('delegates toggleAllContext()', () => {
    assertIsDefined(element.diffElement);
    const stub = sinon.stub(element.diffElement, 'toggleAllContext');
    element.toggleAllContext();
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

  test('passes in noAutoRender', async () => {
    const value = true;
    element.noAutoRender = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.noAutoRender, value);
  });

  test('passes in path', async () => {
    const value = 'some/file/path';
    element.path = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.path, value);
  });

  test('passes in prefs', async () => {
    const value = createDefaultDiffPrefs();
    element.prefs = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.prefs, value);
  });

  test('passes in hidden', async () => {
    const value = true;
    element.hidden = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.hidden, value);
    assert.isNotNull(element.getAttribute('hidden'));
  });

  test('passes in noRenderOnPrefsChange', async () => {
    const value = true;
    element.noRenderOnPrefsChange = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.noRenderOnPrefsChange, value);
  });

  test('passes in lineWrapping', async () => {
    const value = true;
    element.lineWrapping = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.lineWrapping, value);
  });

  test('passes in viewMode', async () => {
    const value = DiffViewMode.SIDE_BY_SIDE;
    element.viewMode = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.viewMode, value);
  });

  test('passes in lineOfInterest', async () => {
    const value = {lineNum: 123, side: Side.LEFT};
    element.lineOfInterest = value;
    await element.updateComplete;
    assertIsDefined(element.diffElement);
    assert.equal(element.diffElement.lineOfInterest, value);
  });

  suite('reportDiff', () => {
    let reportStub: SinonStubbedMember<ReportingService['reportInteraction']>;

    setup(async () => {
      element = await fixture(html`<gr-diff-host></gr-diff-host>`);
      element.changeNum = 123 as NumericChangeId;
      element.path = 'file.txt';
      element.patchRange = createPatchRange(1, 2);
      reportStub = sinon.stub(element.reporting, 'reportInteraction');
      await element.updateComplete;
      reportStub.reset();
    });

    test('undefined', () => {
      element.reportDiff(undefined);
      assert.isFalse(reportStub.called);
    });

    test('diff w/ no delta', () => {
      const diff: DiffInfo = {
        ...createDiff(),
        content: [{ab: ['foo', 'bar']}, {ab: ['baz', 'foo']}],
      };
      element.reportDiff(diff);
      assert.isTrue(reportStub.calledOnce);
      assert.equal(reportStub.lastCall.args[0], 'rebase-percent-zero');
      assert.isUndefined(reportStub.lastCall.args[1]);
    });

    test('diff w/ no rebase delta', () => {
      const diff: DiffInfo = {
        ...createDiff(),
        content: [
          {ab: ['foo', 'bar']},
          {a: ['baz', 'foo']},
          {ab: ['foo', 'bar']},
          {a: ['baz', 'foo'], b: ['bar', 'baz']},
          {ab: ['foo', 'bar']},
          {b: ['baz', 'foo']},
          {ab: ['foo', 'bar']},
        ],
      };
      element.reportDiff(diff);
      assert.isTrue(reportStub.calledOnce);
      assert.equal(reportStub.lastCall.args[0], 'rebase-percent-zero');
      assert.isUndefined(reportStub.lastCall.args[1]);
    });

    test('diff w/ some rebase delta', () => {
      const diff: DiffInfo = {
        ...createDiff(),
        content: [
          {ab: ['foo', 'bar']},
          {a: ['baz', 'foo'], due_to_rebase: true},
          {ab: ['foo', 'bar']},
          {a: ['baz', 'foo'], b: ['bar', 'baz']},
          {ab: ['foo', 'bar']},
          {b: ['baz', 'foo'], due_to_rebase: true},
          {ab: ['foo', 'bar']},
          {a: ['baz', 'foo']},
        ],
      };
      element.reportDiff(diff);
      assert.isTrue(reportStub.calledOnce);
      assert.isTrue(
        reportStub.calledWith('rebase-percent-nonzero', {
          percentRebaseDelta: 50,
        })
      );
    });

    test('diff w/ all rebase delta', () => {
      const diff: DiffInfo = {
        ...createDiff(),
        content: [
          {
            a: ['foo', 'bar'],
            b: ['baz', 'foo'],
            due_to_rebase: true,
          },
        ],
      };
      element.reportDiff(diff);
      assert.isTrue(reportStub.calledOnce);
      assert.isTrue(
        reportStub.calledWith('rebase-percent-nonzero', {
          percentRebaseDelta: 100,
        })
      );
    });

    test('diff against parent event', () => {
      element.patchRange = createPatchRange();
      const diff: DiffInfo = {
        ...createDiff(),
        content: [
          {
            a: ['foo', 'bar'],
            b: ['baz', 'foo'],
          },
        ],
      };
      element.reportDiff(diff);
      assert.isTrue(reportStub.calledOnce);
      assert.equal(reportStub.lastCall.args[0], 'diff-against-parent');
      assert.isUndefined(reportStub.lastCall.args[1]);
    });
  });

  suite('render thread elements', () => {
    test('right start_line:1', async () => {
      const thread: CommentThread = {
        ...createCommentThread([createComment()]),
      };
      element.threads = [thread];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-comment-thread
            class="comment-thread"
            diff-side="right"
            line-num="1"
            slot="right-1"
          >
          </gr-comment-thread>
        `
      );
    });
    test('left start_line:2', async () => {
      const thread: CommentThread = {
        ...createCommentThread([
          createComment({side: CommentSide.PARENT, line: 2}),
        ]),
      };
      element.threads = [thread];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-comment-thread
            class="comment-thread"
            diff-side="left"
            line-num="2"
            slot="left-2"
          >
          </gr-comment-thread>
        `
      );
    });
  });

  suite('render check elements', () => {
    test('start_line:12', async () => {
      const result: RunResult = {
        ...createRunResult(),
        codePointers: [{path: 'a', range: {start_line: 12} as CommentRange}],
      };
      element.checks = [result];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-diff-check-result
            class="comment-thread"
            diff-side="right"
            line-num="12"
            slot="right-12"
          >
          </gr-diff-check-result>
        `
      );
    });

    test('start_line:13 end_line:14 without char positions', async () => {
      const result: RunResult = {
        ...createRunResult(),
        codePointers: [
          {path: 'a', range: {start_line: 13, end_line: 14} as CommentRange},
        ],
      };
      element.checks = [result];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-diff-check-result
            class="comment-thread"
            diff-side="right"
            line-num="14"
            slot="right-14"
          >
          </gr-diff-check-result>
        `
      );
    });

    test('start_line:13 end_line:14 with char positions', async () => {
      const result: RunResult = {
        ...createRunResult(),
        codePointers: [
          {
            path: 'a',
            range: {
              start_line: 13,
              end_line: 14,
              start_character: 5,
              end_character: 7,
            },
          },
        ],
      };
      element.checks = [result];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-diff-check-result
            class="comment-thread"
            diff-side="right"
            line-num="14"
            slot="right-14"
            range='{"start_line":13,"end_line":14,"start_character":5,"end_character":7}'
          >
          </gr-diff-check-result>
        `
      );
    });

    test('empty range', async () => {
      const result: RunResult = {
        ...createRunResult(),
        codePointers: [{path: 'a', range: {} as CommentRange}],
      };
      element.checks = [result];
      await element.updateComplete;
      assert.lightDom.equal(
        element.diffElement,
        /* HTML */ `
          <gr-diff-check-result
            class="comment-thread"
            diff-side="right"
            line-num="FILE"
            slot="right-FILE"
          >
          </gr-diff-check-result>
        `
      );
    });
  });

  suite('create-comment', () => {
    let addDraftSpy: sinon.SinonSpy;

    setup(async () => {
      const commentsModel: CommentsModel = testResolver(commentsModelToken);
      addDraftSpy = sinon.spy(commentsModel, 'addNewDraft');

      account = createAccountDetailWithId(1);
      element.disconnectedCallback();
      element.connectedCallback();
      await element.updateComplete;
    });

    test('creates comments if they do not exist yet', async () => {
      element.patchRange = createPatchRange();
      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            lineNum: 3,
            side: Side.LEFT,
            path: '/p',
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 1);
      const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft1.side, CommentSide.PARENT);
      assert.equal(draft1.range, undefined);
      assert.equal(draft1.patch_set, 1 as RevisionPatchSetNum);

      // Try to fetch a thread with a different range.
      const range = {
        start_line: 1,
        start_character: 1,
        end_line: 1,
        end_character: 3,
      };
      element.patchRange = createPatchRange();

      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            lineNum: 1,
            side: Side.LEFT,
            path: '/p',
            range,
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 2);
      const draft2: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft2.side, CommentSide.PARENT);
      assert.equal(draft2.range, range);
      assert.equal(draft2.patch_set, 1 as RevisionPatchSetNum);
    });

    test('should not be on parent if on the right', async () => {
      element.patchRange = createPatchRange(2, 3);
      // Need to recompute threads.
      await element.updateComplete;
      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: Side.RIGHT,
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 1);
      const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft1.side, CommentSide.REVISION);
      assert.equal(draft1.patch_set, 3 as RevisionPatchSetNum);
    });

    test('should be on parent if right and base is PARENT', () => {
      element.patchRange = createPatchRange();

      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: Side.LEFT,
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 1);
      const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft1.side, CommentSide.PARENT);
      assert.equal(draft1.patch_set, 1 as RevisionPatchSetNum);
    });

    test('should be on parent if right and base negative', () => {
      element.patchRange = createPatchRange(-2, 3);

      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: Side.LEFT,
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 1);
      const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft1.side, CommentSide.PARENT);
      assert.equal(draft1.patch_set, 3 as RevisionPatchSetNum);
      assert.equal(draft1.parent, 2);
    });

    test('should not be on parent otherwise', () => {
      element.patchRange = createPatchRange(2, 3);
      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: Side.LEFT,
          },
        })
      );

      assert.equal(addDraftSpy.callCount, 1);
      const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
      assert.equal(draft1.side, CommentSide.REVISION);
      assert.equal(draft1.patch_set, 2 as RevisionPatchSetNum);
    });

    test(
      'thread should use old file path if first created ' +
        'on patch set (left) before renaming',
      async () => {
        element.patchRange = createPatchRange(2, 3);
        element.file = {basePath: 'file_renamed.txt', path: element.path ?? ''};
        await element.updateComplete;

        element.dispatchEvent(
          new CustomEvent('create-comment', {
            detail: {
              side: Side.LEFT,
              path: '/p',
            },
          })
        );

        assert.equal(addDraftSpy.callCount, 1);
        const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
        assert.equal(draft1.side, CommentSide.REVISION);
        assert.equal(draft1.patch_set, 2 as RevisionPatchSetNum);
        assert.equal(draft1.path, element.file.basePath);
      }
    );

    test(
      'thread should use new file path if first created ' +
        'on patch set (right) after renaming',
      async () => {
        element.patchRange = createPatchRange(2, 3);
        element.file = {basePath: 'file_renamed.txt', path: element.path ?? ''};
        await element.updateComplete;

        element.dispatchEvent(
          new CustomEvent('create-comment', {
            detail: {
              side: Side.RIGHT,
              path: '/p',
            },
          })
        );

        assert.equal(addDraftSpy.callCount, 1);
        const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
        assert.equal(draft1.side, CommentSide.REVISION);
        assert.equal(draft1.patch_set, 3 as RevisionPatchSetNum);
        assert.equal(draft1.path, element.file.path);
      }
    );

    test(
      'thread should use new file path if first created ' +
        'on patch set (left) but is base',
      async () => {
        element.patchRange = createPatchRange();
        element.file = {basePath: 'file_renamed.txt', path: element.path ?? ''};
        await element.updateComplete;

        element.dispatchEvent(
          new CustomEvent('create-comment', {
            detail: {
              side: Side.LEFT,
              path: '/p',
            },
          })
        );

        assert.equal(addDraftSpy.callCount, 1);
        const draft1: DraftInfo = addDraftSpy.lastCall.firstArg;
        assert.equal(draft1.side, CommentSide.PARENT);
        assert.equal(draft1.patch_set, 1 as RevisionPatchSetNum);
        assert.equal(draft1.path, element.file.path);
      }
    );

    test('cannot create thread on an edit', () => {
      const alertSpy = sinon.spy();
      element.addEventListener('show-alert', alertSpy);

      const diffSide = Side.RIGHT;
      element.patchRange = {
        basePatchNum: 3 as BasePatchSetNum,
        patchNum: EDIT,
      };
      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: diffSide,
            path: '/p',
          },
        })
      );

      assert.isFalse(addDraftSpy.called);
      assert.isTrue(alertSpy.called);
    });

    test('cannot create thread on an edit base', () => {
      const alertSpy = sinon.spy();
      element.addEventListener('show-alert', alertSpy);

      const diffSide = Side.LEFT;
      element.patchRange = {
        basePatchNum: PARENT,
        patchNum: EDIT,
      };
      element.dispatchEvent(
        new CustomEvent('create-comment', {
          detail: {
            side: diffSide,
            path: '/p',
          },
        })
      );

      assert.isFalse(addDraftSpy.called);
      assert.isTrue(alertSpy.called);
    });
  });

  suite('syntax layer with syntax_highlighting on', async () => {
    setup(async () => {
      const prefs = {
        ...createDefaultDiffPrefs(),
        line_length: 10,
        show_tabs: true,
        tab_size: 4,
        context: -1,
        syntax_highlighting: true,
      };
      element.patchRange = createPatchRange();
      element.prefs = prefs;
      element.changeNum = 123 as NumericChangeId;
      element.change = createChange();
      element.path = 'some/path';
    });

    test('gr-diff-host provides syntax highlighting layer', async () => {
      getDiffRestApiStub.returns(Promise.resolve(createDiff()));
      await element.updateComplete;
      assertIsDefined(element.diffElement);
      assertIsDefined(element.diffElement.layers);
      assert.equal(element.diffElement.layers[1], element.syntaxLayer);
    });

    test('rendering normal-sized diff does not disable syntax', async () => {
      element.diff = createDiff();
      getDiffRestApiStub.returns(Promise.resolve(element.diff));
      await element.updateComplete;
      assert.isTrue(element.syntaxLayer.enabled);
    });

    test('rendering large diff disables syntax', async () => {
      // Before it renders, set the first diff line to 500 '*' characters.
      getDiffRestApiStub.returns(
        Promise.resolve({
          ...createDiff(),
          content: [
            {
              a: ['*'.repeat(501)],
            },
          ],
        })
      );
      element.reload();
      await element.waitForReloadToRender();
      assert.isFalse(element.syntaxLayer.enabled);
    });

    test('starts syntax layer processing on render event', async () => {
      const stub = sinon
        .stub(element.syntaxLayer, 'process')
        .returns(Promise.resolve());
      getDiffRestApiStub.returns(Promise.resolve(createDiff()));
      await element.reload();
      element.dispatchEvent(
        new CustomEvent('render', {bubbles: true, composed: true})
      );
      assert.isTrue(stub.called);
    });
  });

  suite('syntax layer with syntax_highlighting off', () => {
    setup(async () => {
      const prefs = {
        ...createDefaultDiffPrefs(),
        line_length: 10,
        show_tabs: true,
        tab_size: 4,
        context: -1,
        syntax_highlighting: false,
      };
      element.patchRange = createPatchRange();
      element.change = createChange();
      element.prefs = prefs;
    });

    test('gr-diff-host provides syntax highlighting layer', async () => {
      await element.waitForReloadToRender();
      assertIsDefined(element.diffElement);
      assertIsDefined(element.diffElement.layers);
      assert.equal(element.diffElement.layers[1], element.syntaxLayer);
    });

    test('syntax layer should be disabled', async () => {
      await element.waitForReloadToRender();
      assert.isFalse(element.syntaxLayer.enabled);
    });

    test('still disabled for large diff', async () => {
      getDiffRestApiStub.callsFake(() =>
        Promise.resolve({
          ...createDiff(),
          content: [
            {
              a: ['*'.repeat(501)],
            },
          ],
        })
      );
      await element.waitForReloadToRender();
      assert.isFalse(element.syntaxLayer.enabled);
    });
  });

  suite('coverage layer', () => {
    let coverageProviderStub: SinonStub;
    const exampleRanges = [
      {
        type: CoverageType.COVERED,
        side: Side.RIGHT,
        code_range: {
          start_line: 1,
          end_line: 2,
        },
      },
      {
        type: CoverageType.NOT_COVERED,
        side: Side.RIGHT,
        code_range: {
          start_line: 3,
          end_line: 4,
        },
      },
    ];

    setup(async () => {
      coverageProviderStub = sinon
        .stub()
        .returns(Promise.resolve(exampleRanges));
      element = await fixture(html`<gr-diff-host></gr-diff-host>`);
      element.changeNum = 123 as NumericChangeId;
      element.change = createChange();
      element.path = 'some/path';
      const prefs = {
        ...createDefaultDiffPrefs(),
        line_length: 10,
        show_tabs: true,
        tab_size: 4,
        context: -1,
      };
      element.patchRange = createPatchRange();
      element.prefs = prefs;
      await element.updateComplete;

      getDiffRestApiStub.returns(
        Promise.resolve({
          ...createDiff(),
          content: [{a: ['foo']}],
        })
      );
      testResolver(pluginLoaderToken).pluginsModel.coverageRegister({
        pluginName: 'test-coverage-plugin',
        provider: coverageProviderStub,
      });
      await element.reload();
    });

    test('provider is called with appropriate params', async () => {
      element.patchRange = createPatchRange(1, 3);
      await element.updateComplete;
      await element.reload();
      await element.waitForReloadToRender();
      assert.isTrue(
        coverageProviderStub.calledWithExactly(
          123,
          'some/path',
          1,
          3,
          element.change
        )
      );
    });

    test('provider is called with appropriate params - special patchset values', async () => {
      element.patchRange = createPatchRange();
      await element.waitForReloadToRender();
      assert.isTrue(
        coverageProviderStub.calledWithExactly(
          123,
          'some/path',
          undefined,
          1,
          element.change
        )
      );
    });
  });

  suite('trailing newlines', () => {
    setup(() => {});

    suite('lastChunkForSide', () => {
      test('deltas', () => {
        const diff: DiffInfo = {
          ...createDiff(),
          content: [
            {a: ['foo', 'bar'], b: ['baz']},
            {ab: ['foo', 'bar', 'baz']},
            {b: ['foo']},
          ],
        };
        assert.equal(element.lastChunkForSide(diff, false), diff.content[2]);
        assert.equal(element.lastChunkForSide(diff, true), diff.content[1]);

        diff.content.push({a: ['foo'], b: ['bar']});
        assert.equal(element.lastChunkForSide(diff, false), diff.content[3]);
        assert.equal(element.lastChunkForSide(diff, true), diff.content[3]);
      });

      test('addition with a undefined', () => {
        const diff: DiffInfo = {
          ...createDiff(),
          content: [{b: ['foo', 'bar', 'baz']}],
        };
        assert.equal(element.lastChunkForSide(diff, false), diff.content[0]);
        assert.isNull(element.lastChunkForSide(diff, true));
      });

      test('addition with a empty', () => {
        const diff: DiffInfo = {
          ...createDiff(),
          content: [{a: [], b: ['foo', 'bar', 'baz']}],
        };
        assert.equal(element.lastChunkForSide(diff, false), diff.content[0]);
        assert.isNull(element.lastChunkForSide(diff, true));
      });

      test('deletion with b undefined', () => {
        const diff: DiffInfo = {
          ...createDiff(),
          content: [{a: ['foo', 'bar', 'baz']}],
        };
        assert.isNull(element.lastChunkForSide(diff, false));
        assert.equal(element.lastChunkForSide(diff, true), diff.content[0]);
      });

      test('deletion with b empty', () => {
        const diff: DiffInfo = {
          ...createDiff(),
          content: [{a: ['foo', 'bar', 'baz'], b: []}],
        };
        assert.isNull(element.lastChunkForSide(diff, false));
        assert.equal(element.lastChunkForSide(diff, true), diff.content[0]);
      });

      test('empty', () => {
        const diff: DiffInfo = {...createDiff(), content: []};
        assert.isNull(element.lastChunkForSide(diff, false));
        assert.isNull(element.lastChunkForSide(diff, true));
      });
    });

    suite('hasTrailingNewlines', () => {
      test('shared no trailing', () => {
        const diff = undefined;
        sinon.stub(element, 'lastChunkForSide').returns({ab: ['foo', 'bar']});
        assert.isFalse(element.hasTrailingNewlines(diff, false));
        assert.isFalse(element.hasTrailingNewlines(diff, true));
      });

      test('delta trailing in right', () => {
        const diff = undefined;
        sinon
          .stub(element, 'lastChunkForSide')
          .returns({a: ['foo', 'bar'], b: ['baz', '']});
        assert.isTrue(element.hasTrailingNewlines(diff, false));
        assert.isFalse(element.hasTrailingNewlines(diff, true));
      });

      test('addition', () => {
        const diff: DiffInfo | undefined = undefined;
        sinon
          .stub(element, 'lastChunkForSide')
          .callsFake((_: DiffInfo | undefined, leftSide: boolean) => {
            if (leftSide) {
              return null;
            }
            return {b: ['foo', '']};
          });
        assert.isTrue(element.hasTrailingNewlines(diff, false));
        assert.isNull(element.hasTrailingNewlines(diff, true));
      });

      test('deletion', () => {
        const diff: DiffInfo | undefined = undefined;
        sinon
          .stub(element, 'lastChunkForSide')
          .callsFake((_: DiffInfo | undefined, leftSide: boolean) => {
            if (!leftSide) {
              return null;
            }
            return {a: ['foo']};
          });
        assert.isNull(element.hasTrailingNewlines(diff, false));
        assert.isFalse(element.hasTrailingNewlines(diff, true));
      });
    });
  });
});
