/**
 * @license
 * Copyright (C) 2015 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';
import '../gr-comment-api/gr-comment-api';
import '../../shared/revision-info/revision-info';
import './gr-patch-range-select';
import {GrPatchRangeSelect} from './gr-patch-range-select';
import '../../../test/mocks/comment-api';
import {RevisionInfo as RevisionInfoClass} from '../../shared/revision-info/revision-info';
import {ChangeComments} from '../gr-comment-api/gr-comment-api';
import {stubRestApi} from '../../../test/test-utils';
import {
  BasePatchSetNum,
  EditPatchSetNum,
  PatchSetNum,
  RevisionInfo,
  Timestamp,
  UrlEncodedCommentId,
  PathToCommentsInfoMap,
} from '../../../types/common';
import {EditRevisionInfo, ParsedChangeInfo} from '../../../types/types';
import {SpecialFilePath} from '../../../constants/constants';
import {
  createEditRevision,
  createRevision,
} from '../../../test/test-data-generators';
import {PatchSet} from '../../../utils/patch-set-util';
import {
  DropdownItem,
  GrDropdownList,
} from '../../shared/gr-dropdown-list/gr-dropdown-list';
import {queryAndAssert} from '../../../test/test-utils';

const basicFixture = fixtureFromElement('gr-patch-range-select');

type RevIdToRevisionInfo = {
  [revisionId: string]: RevisionInfo | EditRevisionInfo;
};

suite('gr-patch-range-select tests', () => {
  let element: GrPatchRangeSelect;

  function getInfo(revisions: RevisionInfo[]) {
    const revisionObj: Partial<RevIdToRevisionInfo> = {};
    for (let i = 0; i < revisions.length; i++) {
      revisionObj[i] = revisions[i];
    }
    return new RevisionInfoClass({revisions: revisionObj} as ParsedChangeInfo);
  }

  setup(async () => {
    stubRestApi('getDiffComments').returns(Promise.resolve({}));
    stubRestApi('getDiffRobotComments').returns(Promise.resolve({}));
    stubRestApi('getDiffDrafts').returns(Promise.resolve({}));

    // Element must be wrapped in an element with direct access to the
    // comment API.
    element = basicFixture.instantiate();

    // Stub methods on the changeComments object after changeComments has
    // been initialized.
    element.changeComments = new ChangeComments();
    await element.updateComplete;
  });

  test('enabled/disabled options', () => {
    const patchRange = {
      basePatchNum: 'PARENT' as PatchSetNum,
      patchNum: 3 as PatchSetNum,
    };
    const sortedRevisions = [
      createRevision(3) as RevisionInfo,
      createEditRevision(2) as EditRevisionInfo,
      createRevision(2) as RevisionInfo,
      createRevision(1) as RevisionInfo,
    ];
    for (const patchNum of [1, 2, 3]) {
      assert.isFalse(
        element._computeRightDisabled(
          patchRange.basePatchNum,
          patchNum as PatchSetNum,
          sortedRevisions
        )
      );
    }
    for (const basePatchNum of [1, 2]) {
      assert.isFalse(
        element._computeLeftDisabled(
          basePatchNum as PatchSetNum,
          patchRange.patchNum,
          sortedRevisions
        )
      );
    }
    assert.isTrue(
      element._computeLeftDisabled(3 as PatchSetNum, patchRange.patchNum, [])
    );

    patchRange.basePatchNum = EditPatchSetNum;
    assert.isTrue(
      element._computeLeftDisabled(
        3 as PatchSetNum,
        patchRange.patchNum,
        sortedRevisions
      )
    );
    assert.isTrue(
      element._computeRightDisabled(
        patchRange.basePatchNum,
        1 as PatchSetNum,
        sortedRevisions
      )
    );
    assert.isTrue(
      element._computeRightDisabled(
        patchRange.basePatchNum,
        2 as PatchSetNum,
        sortedRevisions
      )
    );
    assert.isFalse(
      element._computeRightDisabled(
        patchRange.basePatchNum,
        3 as PatchSetNum,
        sortedRevisions
      )
    );
    assert.isTrue(
      element._computeRightDisabled(
        patchRange.basePatchNum,
        EditPatchSetNum,
        sortedRevisions
      )
    );
  });

  test('_computeBaseDropdownContent', () => {
    const availablePatches = [
      {num: 'edit', sha: '1'} as PatchSet,
      {num: 3, sha: '2'} as PatchSet,
      {num: 2, sha: '3'} as PatchSet,
      {num: 1, sha: '4'} as PatchSet,
    ];
    const revisions: RevisionInfo[] = [
      createRevision(2),
      createRevision(3),
      createRevision(1),
      createRevision(4),
    ];
    element.revisionInfo = getInfo(revisions);
    const sortedRevisions = [
      createRevision(3) as RevisionInfo,
      createEditRevision(2) as EditRevisionInfo,
      createRevision(2) as RevisionInfo,
      createRevision(1) as RevisionInfo,
    ];
    const expectedResult: DropdownItem[] = [
      {
        disabled: true,
        triggerText: 'Patchset edit',
        text: 'Patchset edit | 1',
        mobileText: 'edit',
        bottomText: '',
        value: 'edit',
      },
      {
        disabled: true,
        triggerText: 'Patchset 3',
        text: 'Patchset 3 | 2',
        mobileText: '3',
        bottomText: '',
        value: 3,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
      {
        disabled: true,
        triggerText: 'Patchset 2',
        text: 'Patchset 2 | 3',
        mobileText: '2',
        bottomText: '',
        value: 2,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
      {
        disabled: true,
        triggerText: 'Patchset 1',
        text: 'Patchset 1 | 4',
        mobileText: '1',
        bottomText: '',
        value: 1,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
      {
        text: 'Base',
        value: 'PARENT',
      } as DropdownItem,
    ];
    assert.deepEqual(
      element._computeBaseDropdownContent(
        availablePatches,
        1 as PatchSetNum,
        sortedRevisions,
        element.changeComments,
        element.revisionInfo
      ),
      expectedResult
    );
  });

  test('_computeBaseDropdownContent called when patchNum updates', async () => {
    element.revisions = [
      createRevision(2),
      createRevision(3),
      createRevision(1),
      createRevision(4),
    ];
    element.revisionInfo = getInfo(element.revisions);
    element.availablePatches = [
      {num: 1, sha: '1'} as PatchSet,
      {num: 2, sha: '2'} as PatchSet,
      {num: 3, sha: '3'} as PatchSet,
      {num: 'edit', sha: '4'} as PatchSet,
    ];
    element.patchNum = 2 as PatchSetNum;
    element.basePatchNum = 'PARENT' as BasePatchSetNum;
    await element.updateComplete;

    const baseDropDownStub = sinon.stub(element, '_computeBaseDropdownContent');

    // Should be recomputed for each available patch
    element.patchNum = 1 as PatchSetNum;
    await element.updateComplete;
    assert.equal(baseDropDownStub.callCount, 1);
  });

  test('_computeBaseDropdownContent called when changeComments update', async () => {
    element.revisions = [
      createRevision(2),
      createRevision(3),
      createRevision(1),
      createRevision(4),
    ];
    element.revisionInfo = getInfo(element.revisions);
    element.availablePatches = [
      {num: 3, sha: '2'} as PatchSet,
      {num: 2, sha: '3'} as PatchSet,
      {num: 1, sha: '4'} as PatchSet,
    ];
    element.patchNum = 2 as PatchSetNum;
    element.basePatchNum = 'PARENT' as BasePatchSetNum;
    await element.updateComplete;

    // Should be recomputed for each available patch
    const baseDropDownStub = sinon.stub(element, '_computeBaseDropdownContent');
    assert.equal(baseDropDownStub.callCount, 0);
    element.changeComments = new ChangeComments();
    await element.updateComplete;
    assert.equal(baseDropDownStub.callCount, 1);
  });

  test('_computePatchDropdownContent called when basePatchNum updates', async () => {
    element.revisions = [
      createRevision(2),
      createRevision(3),
      createRevision(1),
      createRevision(4),
    ];
    element.revisionInfo = getInfo(element.revisions);
    element.availablePatches = [
      {num: 1, sha: '1'} as PatchSet,
      {num: 2, sha: '2'} as PatchSet,
      {num: 3, sha: '3'} as PatchSet,
      {num: 'edit', sha: '4'} as PatchSet,
    ];
    element.patchNum = 2 as PatchSetNum;
    element.basePatchNum = 'PARENT' as BasePatchSetNum;
    await element.updateComplete;

    // Should be recomputed for each available patch
    const baseDropDownStub = sinon.stub(
      element,
      '_computePatchDropdownContent'
    );
    element.basePatchNum = 1 as BasePatchSetNum;
    await element.updateComplete;
    assert.equal(baseDropDownStub.callCount, 1);
  });

  test('_computePatchDropdownContent', () => {
    const availablePatches: PatchSet[] = [
      {num: 'edit', sha: '1'} as PatchSet,
      {num: 3, sha: '2'} as PatchSet,
      {num: 2, sha: '3'} as PatchSet,
      {num: 1, sha: '4'} as PatchSet,
    ];
    const basePatchNum = 1;
    const sortedRevisions = [
      createRevision(3) as RevisionInfo,
      createEditRevision(2) as EditRevisionInfo,
      createRevision(2, 'description') as RevisionInfo,
      createRevision(1) as RevisionInfo,
    ];

    const expectedResult: DropdownItem[] = [
      {
        disabled: false,
        triggerText: 'edit',
        text: 'edit | 1',
        mobileText: 'edit',
        bottomText: '',
        value: 'edit',
      },
      {
        disabled: false,
        triggerText: 'Patchset 3',
        text: 'Patchset 3 | 2',
        mobileText: '3',
        bottomText: '',
        value: 3,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
      {
        disabled: false,
        triggerText: 'Patchset 2',
        text: 'Patchset 2 | 3',
        mobileText: '2 description',
        bottomText: 'description',
        value: 2,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
      {
        disabled: true,
        triggerText: 'Patchset 1',
        text: 'Patchset 1 | 4',
        mobileText: '1',
        bottomText: '',
        value: 1,
        date: '2020-02-01 01:02:03.000000000' as Timestamp,
      } as DropdownItem,
    ];

    assert.deepEqual(
      element._computePatchDropdownContent(
        availablePatches,
        basePatchNum as BasePatchSetNum,
        sortedRevisions,
        element.changeComments
      ),
      expectedResult
    );
  });

  test('filesWeblinks', async () => {
    element.filesWeblinks = {
      meta_a: [
        {
          name: 'foo',
          url: 'f.oo',
        },
      ],
      meta_b: [
        {
          name: 'bar',
          url: 'ba.r',
        },
      ],
    };
    await element.updateComplete;
    assert.equal(
      queryAndAssert(element, 'a[href="f.oo"]').textContent!.trim(),
      'foo'
    );
    assert.equal(
      queryAndAssert(element, 'a[href="ba.r"]').textContent!.trim(),
      'bar'
    );
  });

  test('_computePatchSetCommentsString', () => {
    // Test string with unresolved comments.
    const comments: PathToCommentsInfoMap = {
      foo: [
        {
          id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
          message: 'test',
          patch_set: 1 as PatchSetNum,
          unresolved: true,
          updated: '2017-10-11 20:48:40.000000000' as Timestamp,
        },
      ],
      bar: [
        {
          id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
          message: 'test',
          patch_set: 1 as PatchSetNum,
          updated: '2017-10-12 20:48:40.000000000' as Timestamp,
        },
        {
          id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
          message: 'test',
          patch_set: 1 as PatchSetNum,
          updated: '2017-10-13 20:48:40.000000000' as Timestamp,
        },
      ],
      abc: [],
      // Patchset level comment does not contribute to the count
      [SpecialFilePath.PATCHSET_LEVEL_COMMENTS]: [
        {
          id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
          message: 'test',
          patch_set: 1 as PatchSetNum,
          unresolved: true,
          updated: '2017-10-11 20:48:40.000000000' as Timestamp,
        },
      ],
    };
    element.changeComments = new ChangeComments(comments);

    assert.equal(
      element._computePatchSetCommentsString(
        element.changeComments,
        1 as PatchSetNum
      ),
      ' (3 comments, 1 unresolved)'
    );

    // Test string with no unresolved comments.
    delete comments['foo'];
    element.changeComments = new ChangeComments(comments);
    assert.equal(
      element._computePatchSetCommentsString(
        element.changeComments,
        1 as PatchSetNum
      ),
      ' (2 comments)'
    );

    // Test string with no comments.
    delete comments['bar'];
    element.changeComments = new ChangeComments(comments);
    assert.equal(
      element._computePatchSetCommentsString(
        element.changeComments,
        1 as PatchSetNum
      ),
      ''
    );
  });

  test('patch-range-change fires', () => {
    const handler = sinon.stub();
    element.basePatchNum = 1 as BasePatchSetNum;
    element.patchNum = 3 as PatchSetNum;
    element.addEventListener('patch-range-change', handler);

    queryAndAssert<GrDropdownList>(
      element,
      '#basePatchDropdown'
    )._handleValueChange('2', [{text: '', value: '2'}]);
    assert.isTrue(handler.calledOnce);
    assert.deepEqual(handler.lastCall.args[0].detail, {
      basePatchNum: 2,
      patchNum: 3,
    });

    // BasePatchNum should not have changed, due to one-way data binding.
    queryAndAssert<GrDropdownList>(
      element,
      '#patchNumDropdown'
    )._handleValueChange('edit', [{text: '', value: 'edit'}]);
    assert.deepEqual(handler.lastCall.args[0].detail, {
      basePatchNum: 1,
      patchNum: 'edit',
    });
  });
});
