/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  GrChangeListSection,
  computeLabelShortcut,
} from './gr-change-list-section';
import '../../../test/common-test-setup';
import './gr-change-list-section';
import '../gr-change-list-item/gr-change-list-item';
import {
  createChange,
  createAccountDetailWithId,
  createAccountWithEmail,
  createServerInfo,
} from '../../../test/test-data-generators';
import {ChangeInfoId, NumericChangeId, Timestamp} from '../../../api/rest-api';
import {
  queryAll,
  query,
  queryAndAssert,
  stubFlags,
  waitUntilObserved,
} from '../../../test/test-utils';
import {GrChangeListItem} from '../gr-change-list-item/gr-change-list-item';
import {ChangeListSection} from '../gr-change-list/gr-change-list';
import {fixture, html, assert} from '@open-wc/testing';
import {ColumnNames} from '../../../constants/constants';

suite('gr-change-list section', () => {
  let element: GrChangeListSection;

  setup(async () => {
    const changeSection: ChangeListSection = {
      name: 'test',
      query: 'test',
      results: [
        {
          ...createChange(),
          _number: 0 as NumericChangeId,
          id: '0' as ChangeInfoId,
        },
        {
          ...createChange(),
          _number: 1 as NumericChangeId,
          id: '1' as ChangeInfoId,
        },
      ],
      emptyStateSlotName: 'test',
    };
    element = await fixture<GrChangeListSection>(
      html`<gr-change-list-section
        .account=${createAccountDetailWithId(1)}
        .config=${createServerInfo()}
        .visibleChangeTableColumns=${Object.values(ColumnNames)}
        .changeSection=${changeSection}
      ></gr-change-list-section> `
    );
  });

  test('renders headers when no changes are selected', () => {
    // TODO: Check table elements. The shadowDom helper does not understand
    // tables interacting with display: contents, even wrapping the element in a
    // table, does not help.
    assert.shadowDom.equal(
      element,
      /* prettier-ignore */ /* HTML */ `
      <td class="selection">
        <input class="selection-checkbox" type="checkbox"/>
      </td>
      #
              SubjectStatusOwnerReviewersCommentsRepoBranchUpdatedSize Status
      <gr-change-list-item
        aria-label="Test subject, section: test"
        role="button"
        tabindex="0"
      >
      </gr-change-list-item>
      <gr-change-list-item
        aria-label="Test subject, section: test"
        role="button"
        tabindex="0"
      >
      </gr-change-list-item>
    `
    );
  });

  test('renders action bar when some changes are selected', async () => {
    assert.isNotOk(query(element, 'gr-change-list-action-bar'));
    element.bulkActionsModel.setState({
      ...element.bulkActionsModel.getState(),
      selectedChangeNums: [1 as NumericChangeId],
    });
    await waitUntilObserved(
      element.bulkActionsModel.selectedChangeNums$,
      s => s.length === 1
    );

    element.requestUpdate();
    await element.updateComplete;
    assert.shadowDom.equal(
      element,
      /* prettier-ignore */ /* HTML */ `
        <td class="selection">
          <input class="selection-checkbox" type="checkbox" />
        </td>
        <gr-change-list-action-bar></gr-change-list-action-bar>
        <gr-change-list-item
          aria-label="Test subject, section: test"
          role="button"
          tabindex="0"
        >
        </gr-change-list-item>
        <gr-change-list-item
          aria-label="Test subject, section: test"
          checked=""
          role="button"
          tabindex="0"
        >
        </gr-change-list-item>
      `
    );
  });

  suite('bulk actions selection', () => {
    let isEnabled: sinon.SinonStub;
    setup(async () => {
      isEnabled = stubFlags('isEnabled');
      isEnabled.returns(true);
      element.requestUpdate();
      await element.updateComplete;
    });

    test('changing section triggers model sync', async () => {
      const syncStub = sinon.stub(element.bulkActionsModel, 'sync');
      assert.isFalse(syncStub.called);
      element.changeSection = {
        name: 'test',
        query: 'test',
        results: [
          {
            ...createChange(),
            _number: 1 as NumericChangeId,
            id: '1' as ChangeInfoId,
          },
        ],
        emptyStateSlotName: 'test',
      };
      await element.updateComplete;

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

    test('actions header is enabled/disabled based on selected changes', async () => {
      element.bulkActionsModel.setState({
        ...element.bulkActionsModel.getState(),
        selectedChangeNums: [],
      });
      await waitUntilObserved(
        element.bulkActionsModel.selectedChangeNums$,
        s => s.length === 0
      );
      assert.isFalse(element.numSelected > 0);

      element.bulkActionsModel.setState({
        ...element.bulkActionsModel.getState(),
        selectedChangeNums: [1 as NumericChangeId],
      });
      await waitUntilObserved(
        element.bulkActionsModel.selectedChangeNums$,
        s => s.length === 1
      );
      assert.isTrue(element.numSelected > 0);
    });

    test('select all checkbox checks all when none are selected', async () => {
      element.changeSection = {
        name: 'test',
        query: 'test',
        results: [
          {
            ...createChange(),
            _number: 1 as NumericChangeId,
            id: '1' as ChangeInfoId,
          },
          {
            ...createChange(),
            _number: 2 as NumericChangeId,
            id: '2' as ChangeInfoId,
          },
        ],
        emptyStateSlotName: 'test',
      };
      element.userModel.setAccount({
        ...createAccountWithEmail('abc@def.com'),
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      });
      await element.updateComplete;
      let rows = queryAll(element, 'gr-change-list-item');
      assert.lengthOf(rows, 2);
      assert.isFalse(
        queryAndAssert<HTMLInputElement>(rows[0], 'input').checked
      );
      assert.isFalse(
        queryAndAssert<HTMLInputElement>(rows[1], 'input').checked
      );

      const checkbox = queryAndAssert<HTMLInputElement>(element, 'input');
      checkbox.click();
      await waitUntilObserved(
        element.bulkActionsModel.selectedChangeNums$,
        s => s.length === 2
      );
      await element.updateComplete;

      rows = queryAll(element, 'gr-change-list-item');
      assert.lengthOf(rows, 2);
      assert.isTrue(queryAndAssert<HTMLInputElement>(rows[0], 'input').checked);
      assert.isTrue(queryAndAssert<HTMLInputElement>(rows[1], 'input').checked);
    });

    test('checkbox matches partial and fully selected state', async () => {
      element.changeSection = {
        name: 'test',
        query: 'test',
        results: [
          {
            ...createChange(),
            _number: 1 as NumericChangeId,
            id: '1' as ChangeInfoId,
          },
          {
            ...createChange(),
            _number: 2 as NumericChangeId,
            id: '2' as ChangeInfoId,
          },
        ],
        emptyStateSlotName: 'test',
      };
      element.userModel.setAccount({
        ...createAccountWithEmail('abc@def.com'),
        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
      });
      await element.updateComplete;
      const rows = queryAll(element, 'gr-change-list-item');

      // zero case
      let checkbox = queryAndAssert<HTMLInputElement>(element, 'input');
      assert.isFalse(checkbox.checked);
      assert.isFalse(checkbox.indeterminate);

      // partial case
      queryAndAssert<HTMLInputElement>(rows[0], 'input').click();
      await element.updateComplete;

      checkbox = queryAndAssert<HTMLInputElement>(element, 'input');
      assert.isTrue(checkbox.indeterminate);

      // plural case
      queryAndAssert<HTMLInputElement>(rows[1], 'input').click();
      await element.updateComplete;

      checkbox = queryAndAssert<HTMLInputElement>(element, 'input');
      assert.isFalse(checkbox.indeterminate);
      assert.isTrue(checkbox.checked);

      // Clicking Check All checkbox when all checkboxes selected unselects
      // all checkboxes
      queryAndAssert<HTMLInputElement>(element, 'input');
      checkbox.click();
      await element.updateComplete;

      assert.isFalse(
        queryAndAssert<HTMLInputElement>(rows[0], 'input').checked
      );
      assert.isFalse(
        queryAndAssert<HTMLInputElement>(rows[1], 'input').checked
      );
    });
  });

  test('no checkbox when logged out', async () => {
    element.changeSection = {
      name: 'test',
      query: 'test',
      results: [
        {
          ...createChange(),
          _number: 1 as NumericChangeId,
          id: '1' as ChangeInfoId,
        },
        {
          ...createChange(),
          _number: 2 as NumericChangeId,
          id: '2' as ChangeInfoId,
        },
      ],
      emptyStateSlotName: 'test',
    };
    element.userModel.setAccount(undefined);
    await element.updateComplete;
    const rows = queryAll(element, 'gr-change-list-item');
    assert.lengthOf(rows, 2);
    assert.isUndefined(query<HTMLInputElement>(rows[0], 'input'));
  });

  test('colspans', async () => {
    element.visibleChangeTableColumns = [];
    element.changeSection = {results: [{...createChange()}]};
    await element.updateComplete;
    const tdItemCount = queryAll<HTMLTableElement>(element, 'td').length;

    element.labelNames = [];
    assert.equal(tdItemCount, element.computeColspan(element.computeColumns()));
  });

  test('computeItemSelected', () => {
    element.selectedIndex = 1;
    assert.isTrue(element.computeItemSelected(1));
    assert.isFalse(element.computeItemSelected(2));
  });

  test('computed fields', () => {
    assert.equal(computeLabelShortcut('Code-Review'), 'CR');
    assert.equal(computeLabelShortcut('Verified'), 'V');
    assert.equal(computeLabelShortcut('Library-Compliance'), 'LC');
    assert.equal(computeLabelShortcut('PolyGerrit-Review'), 'PR');
    assert.equal(computeLabelShortcut('polygerrit-review'), 'PR');
    assert.equal(
      computeLabelShortcut('Invalid-Prolog-Rules-Label-Name--Verified'),
      'V'
    );
    assert.equal(computeLabelShortcut('Some-Special-Label-7'), 'SSL7');
    assert.equal(computeLabelShortcut('--Too----many----dashes---'), 'TMD');
    assert.equal(
      computeLabelShortcut('Really-rather-entirely-too-long-of-a-label-name'),
      'RRETL'
    );
  });

  suite('empty section slots', () => {
    test('empty section', async () => {
      element.changeSection = {results: []};
      await element.updateComplete;
      const listItems = queryAll<GrChangeListItem>(
        element,
        'gr-change-list-item'
      );
      assert.equal(listItems.length, 0);
      const noChangesMsg = queryAll<HTMLTableRowElement>(element, '.noChanges');
      assert.equal(noChangesMsg.length, 1);
    });

    test('are shown on empty sections with slot name', async () => {
      const section = {
        name: 'test',
        query: 'test',
        results: [],
        emptyStateSlotName: 'test',
      };
      element.changeSection = section;
      await element.updateComplete;

      assert.isEmpty(queryAll(element, 'gr-change-list-item'));
      queryAndAssert(element, 'slot[name="test"]');
    });

    test('are not shown on empty sections without slot name', async () => {
      const section = {name: 'test', query: 'test', results: []};
      element.changeSection = section;
      await element.updateComplete;

      assert.isEmpty(queryAll(element, 'gr-change-list-item'));
      assert.notExists(query(element, 'slot[name="test"]'));
    });

    test('are not shown on non-empty sections with slot name', async () => {
      const section = {
        name: 'test',
        query: 'test',
        emptyStateSlotName: 'test',
        results: [
          {
            ...createChange(),
            _number: 0 as NumericChangeId,
            labels: {Verified: {approved: {}}},
          },
        ],
      };
      element.changeSection = section;
      await element.updateComplete;

      assert.isNotEmpty(queryAll(element, 'gr-change-list-item'));
      assert.notExists(query(element, 'slot[name="test"]'));
    });
  });

  suite('dashboard queries', () => {
    test('query without age and limit unchanged', () => {
      const query = 'status:closed owner:me';
      assert.deepEqual(element.processQuery(query), query);
    });

    test('query with age and limit', () => {
      const query = 'status:closed age:1week limit:10 owner:me';
      const expectedQuery = 'status:closed owner:me';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });

    test('query with age', () => {
      const query = 'status:closed age:1week owner:me';
      const expectedQuery = 'status:closed owner:me';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });

    test('query with limit', () => {
      const query = 'status:closed limit:10 owner:me';
      const expectedQuery = 'status:closed owner:me';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });

    test('query with age as value and not key', () => {
      const query = 'status:closed random:age';
      const expectedQuery = 'status:closed random:age';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });

    test('query with limit as value and not key', () => {
      const query = 'status:closed random:limit';
      const expectedQuery = 'status:closed random:limit';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });

    test('query with -age key', () => {
      const query = 'status:closed -age:1week';
      const expectedQuery = 'status:closed';
      assert.deepEqual(element.processQuery(query), expectedQuery);
    });
  });
});
