/**
 * @license
 * Copyright (C) 2017 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-file-list-header.js';
import {FilesExpandedState} from '../gr-file-list-constants.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import 'lodash/lodash.js';
import {createRevisions} from '../../../test/test-data-generators.js';
import {stubRestApi} from '../../../test/test-utils.js';

const basicFixture = fixtureFromElement('gr-file-list-header');

suite('gr-file-list-header tests', () => {
  let element;

  setup(() => {
    stubRestApi('getConfig').returns(Promise.resolve({test: 'config'}));
    stubRestApi('getAccount').returns(Promise.resolve(null));
    element = basicFixture.instantiate();
  });

  teardown(done => {
    flush(() => {
      done();
    });
  });

  test('Diff preferences hidden when no prefs or diffPrefsDisabled', () => {
    element.diffPrefsDisabled = true;
    flush();
    assert.isTrue(element.$.diffPrefsContainer.hidden);

    element.diffPrefsDisabled = false;
    flush();
    assert.isTrue(element.$.diffPrefsContainer.hidden);

    element.diffPrefsDisabled = true;
    element.diffPrefs = {font_size: '12'};
    flush();
    assert.isTrue(element.$.diffPrefsContainer.hidden);

    element.diffPrefsDisabled = false;
    flush();
    assert.isFalse(element.$.diffPrefsContainer.hidden);
  });

  test('_computeDescriptionReadOnly', () => {
    element.loggedIn = false;
    element.change = {owner: {_account_id: 1}};
    element.account = {_account_id: 1};
    assert.equal(element._descriptionReadOnly, true);

    element.loggedIn = true;
    element.change = {owner: {_account_id: 0}};
    element.account = {_account_id: 1};
    assert.equal(element._descriptionReadOnly, true);

    element.loggedIn = true;
    element.change = {owner: {_account_id: 1}};
    element.account = {_account_id: 1};
    assert.equal(element._descriptionReadOnly, false);
  });

  test('_computeDescriptionPlaceholder', () => {
    assert.equal(element._computeDescriptionPlaceholder(true),
        'No patchset description');
    assert.equal(element._computeDescriptionPlaceholder(false),
        'Add patchset description');
  });

  test('description editing', () => {
    const putDescStub = stubRestApi('setDescription')
        .returns(Promise.resolve({ok: true}));

    element.changeNum = '42';
    element.basePatchNum = 'PARENT';
    element.patchNum = 1;

    element.change = {
      change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
      revisions: {
        rev1: {_number: 1, description: 'test', commit: {commit: 'rev1'}},
      },
      current_revision: 'rev1',
      status: 'NEW',
      labels: {},
      actions: {},
      owner: {_account_id: 1},
    };
    element.account = {_account_id: 1};
    element.owner = {_account_id: 1};
    element.loggedIn = true;

    flush();

    // The element has a description, so the account chip should be visible
    element.owner = {_account_id: 1};
    // and the description label should not exist.
    const chip = element.root.querySelector('#descriptionChip');
    let label = element.root.querySelector('#descriptionLabel');

    assert.equal(chip.text, 'test');
    assert.isNotOk(label);

    // Simulate tapping the remove button, but call function directly so that
    // can determine what happens after the promise is resolved.
    return element._handleDescriptionRemoved()
        .then(() => {
          // The API stub should be called with an empty string for the new
          // description.
          assert.equal(putDescStub.lastCall.args[2], '');
          assert.equal(element.change.revisions.rev1.description, '');

          flush();
          // The editable label should now be visible and the chip hidden.
          label = element.root.querySelector('#descriptionLabel');
          assert.isOk(label);
          assert.equal(getComputedStyle(chip).display, 'none');
          assert.notEqual(getComputedStyle(label).display, 'none');
          assert.isFalse(label.readOnly);
          // Edit the label to have a new value of test2, and save.
          label.editing = true;
          label._inputText = 'test2';
          label._save();
          flush();
          // The API stub should be called with an `test2` for the new
          // description.
          assert.equal(putDescStub.callCount, 2);
          assert.equal(putDescStub.lastCall.args[2], 'test2');
        })
        .then(() => {
          flush();
          // The chip should be visible again, and the label hidden.
          assert.equal(element.change.revisions.rev1.description, 'test2');
          assert.equal(getComputedStyle(label).display, 'none');
          assert.notEqual(getComputedStyle(chip).display, 'none');
        });
  });

  test('expandAllDiffs called when expand button clicked', () => {
    element.shownFileCount = 1;
    flush();
    sinon.stub(element, '_expandAllDiffs');
    MockInteractions.tap(element.root.querySelector(
        '#expandBtn'));
    assert.isTrue(element._expandAllDiffs.called);
  });

  test('collapseAllDiffs called when collapse button clicked', () => {
    element.shownFileCount = 1;
    flush();
    sinon.stub(element, '_collapseAllDiffs');
    MockInteractions.tap(element.root.querySelector(
        '#collapseBtn'));
    assert.isTrue(element._collapseAllDiffs.called);
  });

  test('show/hide diffs disabled for large amounts of files', done => {
    const computeSpy = sinon.spy(element, '_fileListActionsVisible');
    element._files = [];
    element.changeNum = '42';
    element.basePatchNum = 'PARENT';
    element.patchNum = '2';
    element.shownFileCount = 1;
    flush(() => {
      assert.isTrue(computeSpy.lastCall.returnValue);
      _.times(element._maxFilesForBulkActions + 1, () => {
        element.shownFileCount = element.shownFileCount + 1;
      });
      assert.isFalse(computeSpy.lastCall.returnValue);
      done();
    });
  });

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

  test('expand/collapse buttons are toggled correctly', () => {
    // Only the expand button should be visible in the initial state when
    // NO files are expanded.
    element.shownFileCount = 10;
    flush();
    const expandBtn = element.shadowRoot.querySelector('#expandBtn');
    const collapseBtn = element.shadowRoot.querySelector('#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;
    flush();
    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;
    flush();
    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;
    flush();
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');
  });

  test('navigateToChange called when range select changes', () => {
    const navigateToChangeStub = sinon.stub(GerritNav, 'navigateToChange');
    element.change = {
      change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
      revisions: {
        rev2: {_number: 2},
        rev1: {_number: 1},
        rev13: {_number: 13},
        rev3: {_number: 3},
      },
      status: 'NEW',
      labels: {},
    };
    element.basePatchNum = 1;
    element.patchNum = 2;

    element._handlePatchChange({detail: {basePatchNum: 1, patchNum: 3}});
    assert.equal(navigateToChangeStub.callCount, 1);
    assert.isTrue(navigateToChangeStub.lastCall
        .calledWithExactly(element.change, 3, 1));
  });

  test('class is applied to file list on old patch set', () => {
    const allPatchSets = [{num: 4}, {num: 2}, {num: 1}];
    assert.equal(element._computePatchInfoClass(1, allPatchSets),
        'patchInfoOldPatchSet');
    assert.equal(element._computePatchInfoClass(2, allPatchSets),
        'patchInfoOldPatchSet');
    assert.equal(element._computePatchInfoClass(4, allPatchSets), '');
  });

  suite('editMode behavior', () => {
    setup(() => {
      element.diffPrefsDisabled = false;
      element.diffPrefs = {};
    });

    const isVisible = el => {
      assert.ok(el);
      return getComputedStyle(el).getPropertyValue('display') !== 'none';
    };

    test('patch specific elements', () => {
      element.editMode = true;
      element.allPatchSets = createRevisions(2);
      flush();

      assert.isFalse(isVisible(element.$.diffPrefsContainer));
      assert.isFalse(isVisible(element.shadowRoot
          .querySelector('.descriptionContainer')));

      element.editMode = false;
      flush();

      assert.isTrue(isVisible(element.shadowRoot
          .querySelector('.descriptionContainer')));
      assert.isTrue(isVisible(element.$.diffPrefsContainer));
    });

    test('edit-controls visibility', () => {
      element.editMode = false;
      flush();
      // on the first render, when editMode is false, editControls are not
      // in the DOM to reduce size of DOM and make first render faster.
      assert.isNull(element.shadowRoot
          .querySelector('#editControls'));

      element.editMode = true;
      flush();
      assert.isTrue(isVisible(element.shadowRoot
          .querySelector('#editControls').parentElement));

      element.editMode = false;
      flush();
      assert.isFalse(isVisible(element.shadowRoot
          .querySelector('#editControls').parentElement));
    });
  });
});

