/**
 * @license
 * Copyright (C) 2016 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-watched-projects-editor';
import {GrWatchedProjectsEditor} from './gr-watched-projects-editor';
import {stubRestApi, waitUntil} from '../../../test/test-utils';
import {ProjectWatchInfo} from '../../../types/common';
import {queryAll, queryAndAssert} from '../../../test/test-utils';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {IronInputElement} from '@polymer/iron-input';
import {assertIsDefined} from '../../../utils/common-util';
import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';

const basicFixture = fixtureFromElement('gr-watched-projects-editor');

suite('gr-watched-projects-editor tests', () => {
  let element: GrWatchedProjectsEditor;
  let suggestionStub: sinon.SinonStub;

  setup(async () => {
    const projects = [
      {
        project: 'project a',
        notify_submitted_changes: true,
        notify_abandoned_changes: true,
      },
      {
        project: 'project b',
        filter: 'filter 1',
        notify_new_changes: true,
      },
      {
        project: 'project b',
        filter: 'filter 2',
      },
      {
        project: 'project c',
        notify_new_changes: true,
        notify_new_patch_sets: true,
        notify_all_comments: true,
      },
    ] as ProjectWatchInfo[];

    stubRestApi('getWatchedProjects').returns(Promise.resolve(projects));
    suggestionStub = stubRestApi('getSuggestedProjects').callsFake(input => {
      if (input.startsWith('th')) {
        return Promise.resolve({
          'the project': {
            id: 'the project',
            state: 'ACTIVE',
            web_links: [],
          },
        });
      } else {
        return Promise.resolve({});
      }
    });

    element = basicFixture.instantiate();

    await element.loadData();
    await element.updateComplete;
  });

  test('renders', () => {
    const rows = queryAndAssert(element, 'table').querySelectorAll('tbody tr');
    assert.equal(rows.length, 4);

    function getKeysOfRow(row: number) {
      const boxes = queryAll(rows[row], 'input[checked]');
      return Array.prototype.map.call(boxes, e => e.getAttribute('data-key'));
    }

    let checkedKeys = getKeysOfRow(0);
    assert.equal(checkedKeys.length, 2);
    assert.equal(checkedKeys[0], 'notify_submitted_changes');
    assert.equal(checkedKeys[1], 'notify_abandoned_changes');

    checkedKeys = getKeysOfRow(1);
    assert.equal(checkedKeys.length, 1);
    assert.equal(checkedKeys[0], 'notify_new_changes');

    checkedKeys = getKeysOfRow(2);
    assert.equal(checkedKeys.length, 0);

    checkedKeys = getKeysOfRow(3);
    assert.equal(checkedKeys.length, 3);
    assert.equal(checkedKeys[0], 'notify_new_changes');
    assert.equal(checkedKeys[1], 'notify_new_patch_sets');
    assert.equal(checkedKeys[2], 'notify_all_comments');
  });

  test('getProjectSuggestions empty', async () => {
    const projects = await element.getProjectSuggestions('nonexistent');
    assert.equal(projects.length, 0);
  });

  test('getProjectSuggestions non-empty', async () => {
    const projects = await element.getProjectSuggestions('the project');
    assert.equal(projects.length, 1);
    assert.equal(projects[0].name, 'the project');
  });

  test('getProjectSuggestions non-empty with two letter project', async () => {
    const projects = await element.getProjectSuggestions('th');
    assert.equal(projects.length, 1);
    assert.equal(projects[0].name, 'the project');
  });

  test('autocompletes repo input', async () => {
    const repoAutocomplete = queryAndAssert<GrAutocomplete>(
      element,
      'gr-autocomplete'
    );
    const repoInput = queryAndAssert<HTMLInputElement>(
      repoAutocomplete,
      '#input'
    );

    repoInput.focus();
    repoAutocomplete.text = 'the';
    await waitUntil(() => suggestionStub.called);
    await repoAutocomplete.updateComplete;

    assert.isTrue(suggestionStub.calledWith('the'));
  });

  test('_canAddProject', () => {
    assert.isFalse(element.canAddProject(null, null, null));

    // Can add a project that is not in the list.
    assert.isTrue(element.canAddProject('project d', null, null));
    assert.isTrue(element.canAddProject('project d', null, 'filter 3'));

    // Cannot add a project that is in the list with no filter.
    assert.isFalse(element.canAddProject('project a', null, null));

    // Can add a project that is in the list if the filter differs.
    assert.isTrue(element.canAddProject('project a', null, 'filter 4'));

    // Cannot add a project that is in the list with the same filter.
    assert.isFalse(element.canAddProject('project b', null, 'filter 1'));
    assert.isFalse(element.canAddProject('project b', null, 'filter 2'));

    // Can add a project that is in the list using a new filter.
    assert.isTrue(element.canAddProject('project b', null, 'filter 3'));

    // Can add a project that is not added by the auto complete
    assert.isTrue(element.canAddProject(null, 'test', null));
  });

  test('getNewProjectIndex', () => {
    // Projects are sorted in ASCII order.
    assert.equal(element.getNewProjectIndex('project A', 'filter'), 0);
    assert.equal(element.getNewProjectIndex('project a', 'filter'), 1);

    // Projects are sorted by filter when the names are equal
    assert.equal(element.getNewProjectIndex('project b', 'filter 0'), 1);
    assert.equal(element.getNewProjectIndex('project b', 'filter 1.5'), 2);
    assert.equal(element.getNewProjectIndex('project b', 'filter 3'), 3);

    // Projects with filters follow those without
    assert.equal(element.getNewProjectIndex('project c', 'filter'), 4);
  });

  test('handleAddProject', () => {
    assertIsDefined(element.newProject, 'newProject');
    element.newProject.value = 'project d';
    element.newProject.setText('project d');
    queryAndAssert<IronInputElement>(element, '#newFilterInput').bindValue = '';

    element.handleAddProject();

    const projects = element.projects!;
    assert.equal(projects.length, 5);
    assert.equal(projects[4].project, 'project d');
    assert.isNotOk(projects[4].filter);
    assert.isTrue(projects[4]._is_local);
  });

  test('_handleAddProject with invalid inputs', () => {
    assertIsDefined(element.newProject, 'newProject');
    element.newProject.value = 'project b';
    element.newProject.setText('project b');
    queryAndAssert<IronInputElement>(element, '#newFilterInput').bindValue =
      'filter 1';
    assertIsDefined(element.newFilter, 'newFilter');
    element.newFilter.value = 'filter 1';

    element.handleAddProject();

    assert.equal(element.projects!.length, 4);
  });

  test('_handleRemoveProject', async () => {
    assert.deepEqual(element.projectsToRemove, []);

    const button = queryAndAssert(
      element,
      'table tbody tr:nth-child(2) gr-button'
    );
    MockInteractions.tap(button);

    await element.updateComplete;

    const rows = queryAndAssert(element, 'table tbody').querySelectorAll('tr');

    assert.equal(rows.length, 3);

    assert.equal(element.projectsToRemove.length, 1);
    assert.equal(element.projectsToRemove[0].project, 'project b');
  });
});
