/**
 * @license
 * Copyright (C) 2018 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 './gr-diff-host.js';
import {GrDiffBuilderImage} from '../gr-diff-builder/gr-diff-builder-image.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {createCommentThreads} from '../../../utils/comment-util.js';
import {Side} from '../../../constants/constants.js';
import {createChange} from '../../../test/test-data-generators.js';
import {CoverageType} from '../../../types/types.js';
import {addListenerForTest, stubRestApi} from '../../../test/test-utils.js';
import {createDefaultDiffPrefs} from '../../../constants/constants.js';

const basicFixture = fixtureFromElement('gr-diff-host');

suite('gr-diff-host tests', () => {
  let element;

  let getLoggedIn;

  setup(() => {
    getLoggedIn = false;
    stubRestApi('getLoggedIn').returns(Promise.resolve(getLoggedIn));
    element = basicFixture.instantiate();
    element.changeNum = 123;
    element.path = 'some/path';
    sinon.stub(element.reporting, 'time');
    sinon.stub(element.reporting, 'timeEnd');
  });

  suite('plugin layers', () => {
    const pluginLayers = [{annotate: () => {}}, {annotate: () => {}}];
    setup(() => {
      element = basicFixture.instantiate();
      sinon.stub(element.jsAPI, 'getDiffLayers').returns(pluginLayers);
      element.changeNum = 123;
      element.path = 'some/path';
    });
    test('plugin layers requested', async () => {
      element.patchRange = {};
      element.change = createChange();
      stubRestApi('getDiff').returns(Promise.resolve({content: []}));
      await element.reload();
      assert(element.jsAPI.getDiffLayers.called);
    });
  });

  test('thread-discard handling', () => {
    const threads = createCommentThreads([
      {
        id: 4711,
        diffSide: Side.LEFT,
        updated: '2015-12-20 15:01:20.396000000',
        patch_set: 1,
        path: 'some/path',
      },
      {
        id: 42,
        diffSide: Side.LEFT,
        updated: '2017-12-20 15:01:20.396000000',
        patch_set: 1,
        path: 'some/path',
      },
    ]);
    element._parentIndex = 1;
    element.changeNum = 2;
    element.path = 'some/path';
    element.projectName = 'Some project';
    const threadEls = threads.map(
        thread => {
          const threadEl = element._createThreadElement(thread);
          // Polymer 2 doesn't fire ready events and doesn't execute
          // observers if element is not added to the Dom.
          // See https://github.com/Polymer/old-docs-site/issues/2322
          // and https://github.com/Polymer/polymer/issues/4526
          element._attachThreadElement(threadEl);
          return threadEl;
        });
    assert.equal(threadEls.length, 2);
    assert.equal(threadEls[0].comments[0].id, 4711);
    assert.equal(threadEls[1].comments[0].id, 42);
    for (const threadEl of threadEls) {
      element.appendChild(threadEl);
    }

    threadEls[0].dispatchEvent(
        new CustomEvent('thread-discard', {detail: {rootId: 4711}}));
    const attachedThreads = element.queryAllEffectiveChildren(
        'gr-comment-thread');
    assert.equal(attachedThreads.length, 1);
    assert.equal(attachedThreads[0].comments[0].id, 42);
  });

  suite('render reporting', () => {
    test('starts total and content timer on render-start', done => {
      element.dispatchEvent(
          new CustomEvent('render-start', {bubbles: true, composed: true}));
      assert.isTrue(element.reporting.time.calledWithExactly(
          'Diff Total Render'));
      assert.isTrue(element.reporting.time.calledWithExactly(
          'Diff Content Render'));
      done();
    });

    test('ends content timer on render-content', () => {
      element.dispatchEvent(
          new CustomEvent('render-content', {bubbles: true, composed: true}));
      assert.isTrue(element.reporting.timeEnd.calledWithExactly(
          'Diff Content Render'));
    });

    test('ends total and syntax timer after syntax layer', async () => {
      sinon.stub(element.reporting, 'diffViewContentDisplayed');
      let notifySyntaxProcessed;
      sinon.stub(element.$.syntaxLayer, 'process').returns(
          new Promise(resolve => {
            notifySyntaxProcessed = resolve;
          })
      );
      stubRestApi('getDiff').returns(Promise.resolve({content: []}));
      element.patchRange = {};
      element.change = createChange();
      element.prefs = createDefaultDiffPrefs();
      element.reload(true);
      // Multiple cascading microtasks are scheduled.
      await flush();
      notifySyntaxProcessed();
      // Multiple cascading microtasks are scheduled.
      await flush();
      assert.isTrue(element.reporting.timeEnd.calledWithExactly(
          'Diff Total Render'));
      assert.isTrue(element.reporting.timeEnd.calledWithExactly(
          'Diff Syntax Render'));
      assert.isTrue(element.reporting.diffViewContentDisplayed.called);
    });

    test('ends total timer w/ no syntax layer processing', async () => {
      stubRestApi('getDiff').returns(Promise.resolve({content: []}));
      element.patchRange = {};
      element.change = createChange();
      element.reload();
      // Multiple cascading microtasks are scheduled.
      await flush();
      // Reporting can be called with other parameters (ex. PluginsLoaded),
      // but only 'Diff Total Render' is important in this test.
      assert.equal(
          element.reporting.timeEnd.getCalls()
              .filter(call => call.calledWithExactly('Diff Total Render'))
              .length,
          1);
    });

    test('completes reload promise after syntax layer processing', async () => {
      let notifySyntaxProcessed;
      sinon.stub(element.$.syntaxLayer, 'process').returns(new Promise(
          resolve => {
            notifySyntaxProcessed = resolve;
          }));
      stubRestApi('getDiff').returns(
          Promise.resolve({content: []}));
      element.patchRange = {};
      element.change = createChange();
      let reloadComplete = false;
      element.prefs = createDefaultDiffPrefs();
      element.reload().then(() => {
        reloadComplete = true;
      });
      // Multiple cascading microtasks are scheduled.
      await flush();
      assert.isFalse(reloadComplete);
      notifySyntaxProcessed();
      // Assert after the notification task is processed.
      await flush();
      assert.isTrue(reloadComplete);
    });
  });

  test('reload() cancels before network resolves', () => {
    const cancelStub = sinon.stub(element.$.diff, 'cancel');

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

    // Needs to be set to something first for it to cancel.
    element.diff = {
      content: [{
        a: ['foo'],
      }],
    };

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

  suite('not logged in', () => {
    setup(() => {
      getLoggedIn = false;
      element = basicFixture.instantiate();
      element.changeNum = 123;
      element.change = createChange();
      element.path = 'some/path';
    });

    test('reload() loads files weblinks', () => {
      const weblinksStub = sinon.stub(GerritNav, '_generateWeblinks')
          .returns({name: 'stubb', url: '#s'});
      stubRestApi('getDiff').returns(Promise.resolve({
        content: [],
      }));
      element.projectName = 'test-project';
      element.path = 'test-path';
      element.commitRange = {baseCommit: 'test-base', commit: 'test-commit'};
      element.patchRange = {};
      return element.reload().then(() => {
        assert.isTrue(weblinksStub.calledTwice);
        assert.isTrue(weblinksStub.firstCall.calledWith({
          commit: 'test-base',
          file: 'test-path',
          options: {
            weblinks: undefined,
          },
          repo: 'test-project',
          type: GerritNav.WeblinkType.FILE}));
        assert.isTrue(weblinksStub.secondCall.calledWith({
          commit: 'test-commit',
          file: 'test-path',
          options: {
            weblinks: undefined,
          },
          repo: 'test-project',
          type: GerritNav.WeblinkType.FILE}));
        assert.deepEqual(element.filesWeblinks, {
          meta_a: [{name: 'stubb', url: '#s'}],
          meta_b: [{name: 'stubb', url: '#s'}],
        });
      });
    });

    test('prefetch getDiff', done => {
      const diffRestApiStub = stubRestApi('getDiff')
          .returns(Promise.resolve({content: []}));
      element.changeNum = 123;
      element.patchRange = {basePatchNum: 1, patchNum: 2};
      element.path = 'file.txt';
      element.prefetchDiff();
      element._getDiff().then(() =>{
        assert.isTrue(diffRestApiStub.calledOnce);
        done();
      });
    });

    test('_getDiff handles null diff responses', done => {
      stubRestApi('getDiff').returns(Promise.resolve(null));
      element.changeNum = 123;
      element.patchRange = {basePatchNum: 1, patchNum: 2};
      element.path = 'file.txt';
      element._getDiff().then(done);
    });

    test('reload resolves on error', () => {
      const onErrStub = sinon.stub(element, '_handleGetDiffError');
      const error = new Response(null, {ok: false, status: 500});
      stubRestApi('getDiff').callsFake(
          (changeNum, basePatchNum, patchNum, path, whitespace, onErr) => {
            onErr(error);
          });
      element.patchRange = {};
      return element.reload().then(() => {
        assert.isTrue(onErrStub.calledOnce);
      });
    });

    suite('_handleGetDiffError', () => {
      let serverErrorStub;
      let pageErrorStub;

      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});
        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(''),
        });
        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!'});
        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;
      let mockFile2;
      setup(() => {
        mockFile1 = {
          body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAAAAAA/w==',
          type: 'image/bmp',
        };
        mockFile2 = {
          body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAA/////w==',
          type: 'image/bmp',
        };

        element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
        element.change = createChange();
        element.comments = {
          left: [],
          right: [],
          meta: {patchRange: element.patchRange},
        };
      });

      test('renders image diffs with same file name', done => {
        const mockDiff = {
          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,
        };
        stubRestApi('getDiff').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',
          },
        }));

        const rendered = () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);

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

          const rightImage =
              element.$.diff.$.diffTable.querySelector('td.right img');
          const rightLabel = element.$.diff.$.diffTable.querySelector(
              'td.right label');
          const rightLabelContent = rightLabel.querySelector('.label');
          const rightLabelName = rightLabel.querySelector('.name');

          assert.isNotOk(rightLabelName);
          assert.isNotOk(leftLabelName);

          let leftLoaded = false;
          let rightLoaded = false;

          leftImage.addEventListener('load', () => {
            assert.isOk(leftImage);
            assert.equal(leftImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile1.body);
            assert.equal(leftLabelContent.textContent, '1×1 image/bmp');
            leftLoaded = true;
            if (rightLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });

          rightImage.addEventListener('load', () => {
            assert.isOk(rightImage);
            assert.equal(rightImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile2.body);
            assert.equal(rightLabelContent.textContent, '1×1 image/bmp');

            rightLoaded = true;
            if (leftLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });
        };

        element.addEventListener('render', rendered);
        element.prefs = createDefaultDiffPrefs();
        element.reload();
      });

      test('renders image diffs with a different file name', done => {
        const mockDiff = {
          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,
        };
        stubRestApi('getDiff').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',
          },
        }));

        const rendered = () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);

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

          const rightImage =
              element.$.diff.$.diffTable.querySelector('td.right img');
          const rightLabel = element.$.diff.$.diffTable.querySelector(
              '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);

          let leftLoaded = false;
          let rightLoaded = false;

          leftImage.addEventListener('load', () => {
            assert.isOk(leftImage);
            assert.equal(leftImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile1.body);
            assert.equal(leftLabelContent.textContent, '1×1 image/bmp');
            leftLoaded = true;
            if (rightLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });

          rightImage.addEventListener('load', () => {
            assert.isOk(rightImage);
            assert.equal(rightImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile2.body);
            assert.equal(rightLabelContent.textContent, '1×1 image/bmp');

            rightLoaded = true;
            if (leftLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });
        };

        element.addEventListener('render', rendered);
        element.prefs = createDefaultDiffPrefs();
        element.reload();
      });

      test('renders added image', done => {
        const mockDiff = {
          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,
        };
        stubRestApi('getDiff').returns(Promise.resolve(mockDiff));
        stubRestApi('getImagesForDiff').returns(Promise.resolve({
          baseImage: null,
          revisionImage: {
            ...mockFile2,
            _expectedType: 'image/jpeg',
            _name: 'carrot2.jpg',
          },
        }));

        element.addEventListener('render', () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);

          const leftImage =
              element.$.diff.$.diffTable.querySelector('td.left img');
          const rightImage =
              element.$.diff.$.diffTable.querySelector('td.right img');

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

        element.prefs = createDefaultDiffPrefs();
        element.reload();
      });

      test('renders removed image', done => {
        const mockDiff = {
          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,
        };
        stubRestApi('getDiff').returns(Promise.resolve(mockDiff));
        stubRestApi('getImagesForDiff').returns(Promise.resolve({
          baseImage: {
            ...mockFile1,
            _expectedType: 'image/jpeg',
            _name: 'carrot.jpg',
          },
          revisionImage: null,
        }));

        element.addEventListener('render', () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);

          const leftImage =
              element.$.diff.$.diffTable.querySelector('td.left img');
          const rightImage =
              element.$.diff.$.diffTable.querySelector('td.right img');

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

        element.prefs = createDefaultDiffPrefs();
        element.reload();
      });

      test('does not render disallowed image type', done => {
        const mockDiff = {
          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';

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

        element.addEventListener('render', () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
          const leftImage =
              element.$.diff.$.diffTable.querySelector('td.left img');
          assert.isNotOk(leftImage);
          done();
        });

        element.prefs = createDefaultDiffPrefs();
        element.reload();
      });
    });
  });

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

  test('delegates getCursorStops()', () => {
    const returnValue = [document.createElement('b')];
    const stub = sinon.stub(element.$.diff, '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;
    const stub = sinon.stub(element.$.diff, 'isRangeSelected')
        .returns(returnValue);
    assert.equal(element.isRangeSelected(), returnValue);
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 0);
  });

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

  suite('blame', () => {
    setup(() => {
      element = basicFixture.instantiate();
      element.changeNum = 123;
      element.path = 'some/path';
    });

    test('clearBlame', () => {
      element._blame = [];
      const setBlameSpy = sinon.spy(element.$.diff.$.diffBuilder, 'setBlame');
      element.clearBlame();
      assert.isNull(element._blame);
      assert.isTrue(setBlameSpy.calledWithExactly(null));
      assert.equal(element.isBlameLoaded, false);
    });

    test('loadBlame', () => {
      const mockBlame = [{id: 'commit id', ranges: [{start: 1, end: 2}]}];
      const showAlertStub = sinon.stub();
      element.addEventListener('show-alert', showAlertStub);
      const getBlameStub = stubRestApi('getBlame')
          .returns(Promise.resolve(mockBlame));
      element.changeNum = 42;
      element.patchRange = {patchNum: 5, basePatchNum: 4};
      element.path = 'foo/bar.baz';
      return element.loadBlame().then(() => {
        assert.isTrue(getBlameStub.calledWithExactly(
            42, 5, 'foo/bar.baz', true));
        assert.isFalse(showAlertStub.called);
        assert.equal(element._blame, mockBlame);
        assert.equal(element.isBlameLoaded, true);
      });
    });

    test('loadBlame empty', () => {
      const mockBlame = [];
      const showAlertStub = sinon.stub();
      element.addEventListener('show-alert', showAlertStub);
      stubRestApi('getBlame')
          .returns(Promise.resolve(mockBlame));
      element.changeNum = 42;
      element.patchRange = {patchNum: 5, basePatchNum: 4};
      element.path = 'foo/bar.baz';
      return element.loadBlame()
          .then(() => {
            assert.isTrue(false, 'Promise should not resolve');
          })
          .catch(() => {
            assert.isTrue(showAlertStub.calledOnce);
            assert.isNull(element._blame);
            assert.equal(element.isBlameLoaded, false);
          });
    });
  });

  test('getThreadEls() returns .comment-threads', () => {
    const threadEl = document.createElement('div');
    threadEl.className = 'comment-thread';
    element.$.diff.appendChild(threadEl);
    assert.deepEqual(element.getThreadEls(), [threadEl]);
  });

  test('delegates addDraftAtLine(el)', () => {
    const param0 = document.createElement('b');
    const stub = sinon.stub(element.$.diff, 'addDraftAtLine');
    element.addDraftAtLine(param0);
    assert.isTrue(stub.calledOnce);
    assert.equal(stub.lastCall.args.length, 1);
    assert.equal(stub.lastCall.args[0], param0);
  });

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

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

  test('passes in changeNum', () => {
    element.changeNum = 12345;
    assert.equal(element.$.diff.changeNum, 12345);
  });

  test('passes in noAutoRender', () => {
    const value = true;
    element.noAutoRender = value;
    assert.equal(element.$.diff.noAutoRender, value);
  });

  test('passes in patchRange', () => {
    const value = {patchNum: 'foo', basePatchNum: 'bar'};
    element.patchRange = value;
    assert.equal(element.$.diff.patchRange, value);
  });

  test('passes in path', () => {
    const value = 'some/file/path';
    element.path = value;
    assert.equal(element.$.diff.path, value);
  });

  test('passes in prefs', () => {
    const value = {};
    element.prefs = value;
    assert.equal(element.$.diff.prefs, value);
  });

  test('passes in changeNum', () => {
    element.changeNum = 12345;
    assert.equal(element.$.diff.changeNum, 12345);
  });

  test('passes in displayLine', () => {
    const value = true;
    element.displayLine = value;
    assert.equal(element.$.diff.displayLine, value);
  });

  test('passes in hidden', () => {
    const value = true;
    element.hidden = value;
    assert.equal(element.$.diff.hidden, value);
    assert.isNotNull(element.getAttribute('hidden'));
  });

  test('passes in noRenderOnPrefsChange', () => {
    const value = true;
    element.noRenderOnPrefsChange = value;
    assert.equal(element.$.diff.noRenderOnPrefsChange, value);
  });

  test('passes in lineWrapping', () => {
    const value = true;
    element.lineWrapping = value;
    assert.equal(element.$.diff.lineWrapping, value);
  });

  test('passes in viewMode', () => {
    const value = 'SIDE_BY_SIDE';
    element.viewMode = value;
    assert.equal(element.$.diff.viewMode, value);
  });

  test('passes in lineOfInterest', () => {
    const value = {number: 123, leftSide: true};
    element.lineOfInterest = value;
    assert.equal(element.$.diff.lineOfInterest, value);
  });

  suite('_reportDiff', () => {
    let reportStub;

    setup(() => {
      element = basicFixture.instantiate();
      element.changeNum = 123;
      element.path = 'file.txt';
      element.patchRange = {basePatchNum: 1};
      reportStub = sinon.stub(element.reporting, 'reportInteraction');
    });

    test('null and content-less', () => {
      element._reportDiff(null);
      assert.isFalse(reportStub.called);

      element._reportDiff({});
      assert.isFalse(reportStub.called);
    });

    test('diff w/ no delta', () => {
      const diff = {
        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 = {
        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 = {
        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 = {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.basePatchNum = 'PARENT';
      const diff = {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('create-comment', () => {
    test('creates comments if they do not exist yet', () => {
      const diffSide = Side.LEFT;
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 2,
      };

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

      let threads = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread');

      assert.equal(threads.length, 1);
      assert.equal(threads[0].diffSide, diffSide);
      assert.isTrue(threads[0].isOnParent);
      assert.equal(threads[0].range, undefined);
      assert.equal(threads[0].patchNum, 2);

      // 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 = {
        basePatchNum: 'PARENT',
        patchNum: 3,
      };

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

      threads = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread');

      assert.equal(threads.length, 2);
      assert.equal(threads[1].diffSide, diffSide);
      assert.isTrue(threads[0].isOnParent);
      assert.equal(threads[1].range, range);
      assert.equal(threads[1].patchNum, 3);
    });

    test('should not be on parent if on the right', () => {
      element.patchRange = {
        basePatchNum: 2,
        patchNum: 3,
      };

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

      const thread = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread')[0];

      assert.isFalse(thread.isOnParent);
    });

    test('should be on parent if right and base is PARENT', () => {
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 3,
      };

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

      const thread = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread')[0];

      assert.isTrue(thread.isOnParent);
    });

    test('should be on parent if right and base negative', () => {
      element.patchRange = {
        basePatchNum: -2, // merge parents have negative numbers
        patchNum: 3,
      };

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

      const thread = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread')[0];

      assert.isTrue(thread.isOnParent);
    });

    test('should not be on parent otherwise', () => {
      element.patchRange = {
        basePatchNum: 2, // merge parents have negative numbers
        patchNum: 3,
      };

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

      const thread = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread')[0];

      assert.isFalse(thread.isOnParent);
    });

    test('thread should use old file path if first created ' +
    'on patch set (left) before renaming', () => {
      const diffSide = Side.LEFT;
      element.patchRange = {
        basePatchNum: 2,
        patchNum: 3,
      };
      element.file = {basePath: 'file_renamed.txt', path: element.path};

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

      const threads = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread');

      assert.equal(threads.length, 1);
      assert.equal(threads[0].diffSide, diffSide);
      assert.equal(threads[0].path, element.file.basePath);
    });

    test('thread should use new file path if first created' +
    'on patch set (right) after renaming', () => {
      const diffSide = Side.RIGHT;
      element.patchRange = {
        basePatchNum: 2,
        patchNum: 3,
      };
      element.file = {basePath: 'file_renamed.txt', path: element.path};

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

      const threads = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread');

      assert.equal(threads.length, 1);
      assert.equal(threads[0].diffSide, diffSide);
      assert.equal(threads[0].path, element.file.path);
    });

    test('thread should use new file path if first created' +
    'on patch set (left) but is base', () => {
      const diffSide = Side.LEFT;
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 3,
      };
      element.file = {basePath: 'file_renamed.txt', path: element.path};

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

      const threads = dom(element.$.diff)
          .queryDistributedElements('gr-comment-thread');

      assert.equal(threads.length, 1);
      assert.equal(threads[0].diffSide, diffSide);
      assert.equal(threads[0].path, element.file.path);
    });
  });

  test('_filterThreadElsForLocation with no threads', () => {
    const line = {beforeNumber: 3, afterNumber: 5};

    const threads = [];
    assert.deepEqual(element._filterThreadElsForLocation(threads, line), []);
    assert.deepEqual(element._filterThreadElsForLocation(threads, line,
        Side.LEFT), []);
    assert.deepEqual(element._filterThreadElsForLocation(threads, line,
        Side.RIGHT), []);
  });

  test('_filterThreadElsForLocation for line comments', () => {
    const line = {beforeNumber: 3, afterNumber: 5};

    const l3 = document.createElement('div');
    l3.setAttribute('line-num', 3);
    l3.setAttribute('diff-side', Side.LEFT);

    const l5 = document.createElement('div');
    l5.setAttribute('line-num', 5);
    l5.setAttribute('diff-side', Side.LEFT);

    const r3 = document.createElement('div');
    r3.setAttribute('line-num', 3);
    r3.setAttribute('diff-side', Side.RIGHT);

    const r5 = document.createElement('div');
    r5.setAttribute('line-num', 5);
    r5.setAttribute('diff-side', Side.RIGHT);

    const threadEls = [l3, l5, r3, r5];
    assert.deepEqual(element._filterThreadElsForLocation(threadEls, line,
        Side.LEFT), [l3]);
    assert.deepEqual(element._filterThreadElsForLocation(threadEls, line,
        Side.RIGHT), [r5]);
  });

  test('_filterThreadElsForLocation for file comments', () => {
    const line = {beforeNumber: 'FILE', afterNumber: 'FILE'};

    const l = document.createElement('div');
    l.setAttribute('diff-side', Side.LEFT);
    l.setAttribute('line-num', 'FILE');

    const r = document.createElement('div');
    r.setAttribute('diff-side', Side.RIGHT);
    r.setAttribute('line-num', 'FILE');

    const threadEls = [l, r];
    assert.deepEqual(element._filterThreadElsForLocation(threadEls, line,
        Side.LEFT), [l]);
    assert.deepEqual(element._filterThreadElsForLocation(threadEls, line,
        Side.RIGHT), [r]);
  });

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

    test('gr-diff-host provides syntax highlighting layer', async () => {
      stubRestApi('getDiff').returns(Promise.resolve({content: []}));
      await element.reload();
      assert.equal(element.$.diff.layers[0], element.$.syntaxLayer);
    });

    test('rendering normal-sized diff does not disable syntax', () => {
      element.diff = {
        content: [{
          a: ['foo'],
        }],
      };
      assert.isTrue(element.$.syntaxLayer.enabled);
    });

    test('rendering large diff disables syntax', () => {
      // Before it renders, set the first diff line to 500 '*' characters.
      element.diff = {
        content: [{
          a: [new Array(501).join('*')],
        }],
      };
      assert.isFalse(element.$.syntaxLayer.enabled);
    });

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

  suite('syntax layer with syntax_highlighting off', () => {
    setup(() => {
      const prefs = {
        line_length: 10,
        show_tabs: true,
        tab_size: 4,
        context: -1,
      };
      element.diff = {
        content: [{
          a: ['foo'],
        }],
      };
      element.patchRange = {};
      element.change = createChange();
      element.prefs = prefs;
    });

    test('gr-diff-host provides syntax highlighting layer', async () => {
      stubRestApi('getDiff').returns(Promise.resolve({content: []}));
      await element.reload();
      assert.equal(element.$.diff.layers[0], element.$.syntaxLayer);
    });

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

    test('still disabled for large diff', () => {
      // Before it renders, set the first diff line to 500 '*' characters.
      element.diff = {
        content: [{
          a: [new Array(501).join('*')],
        }],
      };
      assert.isFalse(element.$.syntaxLayer.enabled);
    });
  });

  suite('coverage layer', () => {
    let notifyStub;
    let coverageProviderStub;
    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(() => {
      notifyStub = sinon.stub();
      coverageProviderStub = sinon.stub().returns(
          Promise.resolve(exampleRanges));

      element = basicFixture.instantiate();
      sinon.stub(element.jsAPI, 'getCoverageAnnotationApis').returns(
          Promise.resolve([{
            notify: notifyStub,
            getCoverageProvider() {
              return coverageProviderStub;
            },
          }]));
      element.changeNum = 123;
      element.change = createChange();
      element.path = 'some/path';
      const prefs = {
        line_length: 10,
        show_tabs: true,
        tab_size: 4,
        context: -1,
      };
      element.diff = {
        content: [{
          a: ['foo'],
        }],
      };
      element.patchRange = {};
      element.prefs = prefs;
      stubRestApi('getDiff').returns(Promise.resolve(element.diff));
    });

    test('getCoverageAnnotationApis should be called', async () => {
      await element.reload();
      assert.isTrue(element.jsAPI.getCoverageAnnotationApis.calledOnce);
    });

    test('coverageRangeChanged should be called', async () => {
      await element.reload();
      assert.equal(notifyStub.callCount, 2);
      assert.isTrue(notifyStub.calledWithExactly(
          'some/path', 1, 2, Side.RIGHT));
      assert.isTrue(notifyStub.calledWithExactly(
          'some/path', 3, 4, Side.RIGHT));
    });

    test('provider is called with appropriate params', async () => {
      element.patchRange.basePatchNum = 1;
      element.patchRange.patchNum = 3;

      await element.reload();
      assert.isTrue(coverageProviderStub.calledWithExactly(
          123, 'some/path', 1, 3, element.change));
    });

    test('provider is called with appropriate params - special patchset values',
        async () => {
          element.patchRange.basePatchNum = 'PARENT';
          element.patchRange.patchNum = 'invalid';

          await element.reload();
          assert.isTrue(coverageProviderStub.calledWithExactly(
              123, 'some/path', undefined, undefined, element.change));
        });
  });

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

    suite('_lastChunkForSide', () => {
      test('deltas', () => {
        const diff = {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 = {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 = {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 = {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 = {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 = {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 = undefined;
        sinon.stub(element, '_lastChunkForSide').callsFake((diff, leftSide) => {
          if (leftSide) { return null; }
          return {b: ['foo', '']};
        });
        assert.isTrue(element._hasTrailingNewlines(diff, false));
        assert.isNull(element._hasTrailingNewlines(diff, true));
      });

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

