/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-file-list-header';
import {FilesExpandedState} from '../gr-file-list-constants';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {createChange, createRevision} from '../../../test/test-data-generators';
import {
  isVisible,
  query,
  queryAndAssert,
  stubRestApi,
} from '../../../test/test-utils';
import {GrFileListHeader} from './gr-file-list-header';
import {
  BasePatchSetNum,
  ChangeId,
  NumericChangeId,
  PARENT,
  PatchSetNum,
  PatchSetNumber,
} from '../../../types/common';
import {ChangeInfo, ChangeStatus} from '../../../api/rest-api';
import {PatchSet} from '../../../utils/patch-set-util';
import {createDefaultDiffPrefs} from '../../../constants/constants';
import {fixture, html, assert} from '@open-wc/testing';
import {GrButton} from '../../shared/gr-button/gr-button';
import {testResolver} from '../../../test/common-test-setup';

suite('gr-file-list-header tests', () => {
  let element: GrFileListHeader;
  const change: ChangeInfo = {
    ...createChange(),
    change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca' as ChangeId,
    revisions: {
      rev2: createRevision(2),
      rev1: createRevision(1),
      rev13: createRevision(13),
      rev3: createRevision(3),
    },
    status: 'NEW' as ChangeStatus,
    labels: {},
  };

  setup(async () => {
    stubRestApi('getAccount').resolves(undefined);
    element = await fixture(
      html`<gr-file-list-header
        .change=${change}
        .shownFileCount=${3}
      ></gr-file-list-header>`
    );
    element.diffPrefs = createDefaultDiffPrefs();
  });

  test('render', () => {
    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <div class="patchInfo-header">
          <div class="patchInfo-left">
            <div class="patchInfoContent">
              <gr-patch-range-select id="rangeSelect"> </gr-patch-range-select>
              <span class="separator"> </span>
              <gr-commit-info> </gr-commit-info>
              <span class="container latestPatchContainer">
                <span class="separator"> </span>
                <a> Go to latest patch set </a>
              </span>
            </div>
          </div>
          <div class="rightControls">
            <div class="fileViewActions">
              <span class="fileViewActionsLabel"> Diff view: </span>
              <gr-diff-mode-selector id="modeSelect"> </gr-diff-mode-selector>
              <span class="hideOnEdit" hidden="" id="diffPrefsContainer">
                <gr-tooltip-content has-tooltip="" title="Diff preferences">
                  <gr-button
                    aria-disabled="false"
                    class="desktop prefsButton"
                    link=""
                    role="button"
                    tabindex="0"
                  >
                    <gr-icon filled icon="settings"></gr-icon>
                  </gr-button>
                </gr-tooltip-content>
              </span>
              <span class="separator"> </span>
            </div>
            <span class="desktop downloadContainer">
              <gr-tooltip-content
                has-tooltip=""
                title="Open download overlay (shortcut: d)"
              >
                <gr-button
                  aria-disabled="false"
                  class="download"
                  link=""
                  role="button"
                  tabindex="0"
                >
                  Download
                </gr-button>
              </gr-tooltip-content>
            </span>
            <gr-tooltip-content
              has-tooltip=""
              title="Show/hide all inline diffs (shortcut: I)"
            >
              <gr-button
                aria-disabled="false"
                id="expandBtn"
                link=""
                role="button"
                tabindex="0"
              >
                Expand All
              </gr-button>
            </gr-tooltip-content>
            <gr-tooltip-content
              has-tooltip=""
              title="Show/hide all inline diffs (shortcut: I)"
            >
              <gr-button
                aria-disabled="false"
                id="collapseBtn"
                link=""
                role="button"
                tabindex="0"
              >
                Collapse All
              </gr-button>
            </gr-tooltip-content>
          </div>
        </div>
      `
    );
  });

  test('Diff preferences hidden when no prefs', async () => {
    assert.isTrue(
      queryAndAssert<HTMLElement>(element, '#diffPrefsContainer').hidden
    );

    element.diffPrefs = createDefaultDiffPrefs();
    element.loggedIn = true;
    await element.updateComplete;

    assert.isFalse(
      queryAndAssert<HTMLElement>(element, '#diffPrefsContainer').hidden
    );
  });

  test('expandAllDiffs called when expand button clicked', async () => {
    const expandDiffsListener = sinon.stub();
    element.addEventListener('expand-diffs', expandDiffsListener);

    queryAndAssert<GrButton>(element, 'gr-button#expandBtn').click();
    await element.updateComplete;

    assert.isTrue(expandDiffsListener.called);
  });

  test('collapseAllDiffs called when collapse button clicked', async () => {
    const collapseAllDiffsListener = sinon.stub();
    element.addEventListener('collapse-diffs', collapseAllDiffsListener);

    queryAndAssert<GrButton>(element, 'gr-button#collapseBtn').click();
    await element.updateComplete;

    assert.isTrue(collapseAllDiffsListener.called);
  });

  test('show/hide diffs disabled for large amounts of files', async () => {
    element.changeNum = 42 as NumericChangeId;
    element.basePatchNum = PARENT;
    element.patchNum = '2' as PatchSetNum;
    element.shownFileCount = 1;
    await element.updateComplete;

    queryAndAssert(element, 'gr-button#expandBtn');
    queryAndAssert(element, 'gr-button#collapseBtn');
    assert.isNotOk(query(element, '.warning'));

    element.shownFileCount = 226; // more than element.maxFilesForBulkActions
    await element.updateComplete;

    assert.isNotOk(query(element, 'gr-button#expandBtn'));
    assert.isNotOk(query(element, 'gr-button#collapseBtn'));
    queryAndAssert(element, '.warning');
  });

  test('fileViewActions are properly hidden', async () => {
    const actions = queryAndAssert(element, '.fileViewActions');
    assert.equal(getComputedStyle(actions).display, 'none');
    element.filesExpanded = FilesExpandedState.SOME;
    await element.updateComplete;
    assert.notEqual(getComputedStyle(actions).display, 'none');
    element.filesExpanded = FilesExpandedState.ALL;
    await element.updateComplete;
    assert.notEqual(getComputedStyle(actions).display, 'none');
    element.filesExpanded = FilesExpandedState.NONE;
    await element.updateComplete;
    assert.equal(getComputedStyle(actions).display, 'none');
  });

  test('expand/collapse buttons are toggled correctly', async () => {
    // Only the expand button should be visible in the initial state when
    // NO files are expanded.
    element.shownFileCount = 10;
    await element.updateComplete;
    const expandBtn = queryAndAssert(element, '#expandBtn');
    const collapseBtn = queryAndAssert(element, '#collapseBtn');
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');

    // Both expand and collapse buttons should be visible when SOME files are
    // expanded.
    element.filesExpanded = FilesExpandedState.SOME;
    await element.updateComplete;
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.notEqual(getComputedStyle(collapseBtn).display, 'none');

    // Only the collapse button should be visible when ALL files are expanded.
    element.filesExpanded = FilesExpandedState.ALL;
    await element.updateComplete;
    assert.equal(getComputedStyle(expandBtn).display, 'none');
    assert.notEqual(getComputedStyle(collapseBtn).display, 'none');

    // Only the expand button should be visible when NO files are expanded.
    element.filesExpanded = FilesExpandedState.NONE;
    await element.updateComplete;
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');
  });

  test('setUrl called when range select changes', async () => {
    const setUrlStub = sinon.stub(testResolver(navigationToken), 'setUrl');
    element.basePatchNum = 1 as BasePatchSetNum;
    element.patchNum = 2 as PatchSetNum;
    await element.updateComplete;

    element.handlePatchChange({
      detail: {basePatchNum: 1, patchNum: 3},
    } as CustomEvent);
    await element.updateComplete;

    assert.equal(setUrlStub.callCount, 1);
    assert.equal(setUrlStub.lastCall.firstArg, '/c/test-project/+/42/1..3');
  });

  test('class is applied to file list on old patch set', () => {
    const allPatchSets: PatchSet[] = [
      {num: 4 as PatchSetNumber, desc: undefined, sha: ''},
      {num: 2 as PatchSetNumber, desc: undefined, sha: ''},
      {num: 1 as PatchSetNumber, desc: undefined, sha: ''},
    ];
    assert.equal(
      element.computePatchInfoClass(1 as PatchSetNum, allPatchSets),
      'patchInfoOldPatchSet'
    );
    assert.equal(
      element.computePatchInfoClass(2 as PatchSetNum, allPatchSets),
      'patchInfoOldPatchSet'
    );
    assert.equal(
      element.computePatchInfoClass(4 as PatchSetNum, allPatchSets),
      ''
    );
  });

  suite('editMode behavior', () => {
    setup(async () => {
      element.loggedIn = true;
      await element.updateComplete;
    });

    test('patch specific elements', async () => {
      element.editMode = true;
      element.allPatchSets = [
        {num: 1 as PatchSetNumber, desc: undefined, sha: ''},
        {num: 2 as PatchSetNumber, desc: undefined, sha: ''},
        {num: 3 as PatchSetNumber, desc: undefined, sha: ''},
      ];
      await element.updateComplete;

      assert.isFalse(
        isVisible(queryAndAssert<HTMLElement>(element, '#diffPrefsContainer'))
      );

      element.editMode = false;
      await element.updateComplete;

      assert.isTrue(
        isVisible(queryAndAssert<HTMLElement>(element, '#diffPrefsContainer'))
      );
    });

    test('edit-controls visibility', async () => {
      element.editMode = false;
      await element.updateComplete;

      assert.isNotOk(query(element, '#editControls'));

      element.editMode = true;
      await element.updateComplete;

      assert.isTrue(
        isVisible(queryAndAssert<HTMLElement>(element, '#editControls'))
      );

      element.editMode = false;
      await element.updateComplete;

      assert.isNotOk(query<HTMLElement>(element, '#editControls'));
    });
  });
});
