/**
 * @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';
import './gr-rule-editor';
import {GrRuleEditor} from './gr-rule-editor';
import {AccessPermissionId} from '../../../utils/access-util';
import {query, queryAll, queryAndAssert} from '../../../test/test-utils';
import {GrButton} from '../../shared/gr-button/gr-button';
import {GrSelect} from '../../shared/gr-select/gr-select';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';

const basicFixture = fixtureFromElement('gr-rule-editor');

suite('gr-rule-editor tests', () => {
  let element: GrRuleEditor;

  setup(async () => {
    element = basicFixture.instantiate() as GrRuleEditor;
    await element.updateComplete;
  });

  suite('unit tests', () => {
    test('computeForce and computeForceOptions', () => {
      const ForcePushOptions = {
        ALLOW: [
          {name: 'Allow pushing (but not force pushing)', value: false},
          {name: 'Allow pushing with or without force', value: true},
        ],
        BLOCK: [
          {name: 'Block pushing with or without force', value: false},
          {name: 'Block force pushing', value: true},
        ],
      };

      const FORCE_EDIT_OPTIONS = [
        {
          name: 'No Force Edit',
          value: false,
        },
        {
          name: 'Force Edit',
          value: true,
        },
      ];
      element.permission = 'push' as AccessPermissionId;
      let action = 'ALLOW';
      assert.isTrue(element.computeForce(action));
      assert.deepEqual(
        element.computeForceOptions(action),
        ForcePushOptions.ALLOW
      );

      action = 'BLOCK';
      assert.isTrue(element.computeForce(action));
      assert.deepEqual(
        element.computeForceOptions(action),
        ForcePushOptions.BLOCK
      );

      action = 'DENY';
      assert.isFalse(element.computeForce(action));
      assert.equal(element.computeForceOptions(action).length, 0);

      element.permission = 'editTopicName' as AccessPermissionId;
      assert.isTrue(element.computeForce());
      assert.deepEqual(element.computeForceOptions(), FORCE_EDIT_OPTIONS);
      element.permission = 'submit' as AccessPermissionId;
      assert.isFalse(element.computeForce());
      assert.deepEqual(element.computeForceOptions(), []);
    });

    test('computeSectionClass', () => {
      element.deleted = true;
      element.editing = false;
      assert.equal(element.computeSectionClass(), 'deleted');

      element.deleted = false;
      assert.equal(element.computeSectionClass(), '');

      element.editing = true;
      assert.equal(element.computeSectionClass(), 'editing');

      element.deleted = true;
      assert.equal(element.computeSectionClass(), 'editing deleted');
    });

    test('getDefaultRuleValues', () => {
      element.permission = 'priority' as AccessPermissionId;
      assert.deepEqual(element.getDefaultRuleValues(), {
        action: 'BATCH',
      });
      element.permission = 'label-Code-Review' as AccessPermissionId;
      element.label = {
        values: [
          {value: -2, text: 'This shall not be merged'},
          {value: -1, text: 'I would prefer this is not merged as is'},
          {value: -0, text: 'No score'},
          {value: 1, text: 'Looks good to me, but someone else must approve'},
          {value: 2, text: 'Looks good to me, approved'},
        ],
      };
      assert.deepEqual(element.getDefaultRuleValues(), {
        action: 'ALLOW',
        max: 2,
        min: -2,
      });
      element.permission = 'push' as AccessPermissionId;
      element.label = undefined;
      assert.deepEqual(element.getDefaultRuleValues(), {
        action: 'ALLOW',
        force: false,
      });
      element.permission = 'submit' as AccessPermissionId;
      assert.deepEqual(element.getDefaultRuleValues(), {
        action: 'ALLOW',
      });
    });

    test('setDefaultRuleValues', async () => {
      element.rule = {value: {}};
      const defaultValue = {action: 'ALLOW'};
      const getDefaultRuleValuesStub = sinon
        .stub(element, 'getDefaultRuleValues')
        .returns(defaultValue);
      element.setDefaultRuleValues();
      assert.isTrue(getDefaultRuleValuesStub.called);
      assert.equal(element.rule!.value, defaultValue);
    });

    test('computeOptions', () => {
      const PRIORITY_OPTIONS = ['BATCH', 'INTERACTIVE'];
      const DROPDOWN_OPTIONS = ['ALLOW', 'DENY', 'BLOCK'];
      element.permission = 'priority' as AccessPermissionId;
      assert.deepEqual(element.computeOptions(), PRIORITY_OPTIONS);
      element.permission = 'submit' as AccessPermissionId;
      assert.deepEqual(element.computeOptions(), DROPDOWN_OPTIONS);
    });

    test('handleValueChange', () => {
      const modifiedHandler = sinon.stub();
      element.rule = {value: {}};
      element.addEventListener('access-modified', modifiedHandler);
      element.handleValueChange();
      assert.isNotOk(element.rule!.value!.modified);
      element.originalRuleValues = {};
      element.handleValueChange();
      assert.isTrue(element.rule!.value!.modified);
      assert.isTrue(modifiedHandler.called);
    });

    test('handleAccessSaved', () => {
      const originalValue = {action: 'DENY'};
      const newValue = {action: 'ALLOW'};
      element.originalRuleValues = originalValue;
      element.rule = {value: newValue};
      element.handleAccessSaved();
      assert.deepEqual(element.originalRuleValues, newValue);
    });

    test('setOriginalRuleValues', () => {
      element.rule = {
        value: {
          action: 'ALLOW',
          force: false,
        },
      };
      element.setOriginalRuleValues();
      assert.deepEqual(element.originalRuleValues, element.rule.value);
    });
  });

  suite('already existing generic rule', () => {
    setup(async () => {
      element.groupName = 'Group Name';
      element.permission = 'submit' as AccessPermissionId;
      element.rule = {
        value: {
          action: 'ALLOW',
          force: false,
        },
      };
      element.section = 'refs/*';
      element.setupValues();
      element.setOriginalRuleValues();
      await element.updateComplete;
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      assert.deepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('values are set correctly', () => {
      assert.equal(
        queryAndAssert<GrSelect>(element, '#action').bindValue,
        element.rule!.value!.action
      );
      assert.isNotOk(query<GrSelect>(element, '#labelMin'));
      assert.isNotOk(query<GrSelect>(element, '#labelMax'));
      assert.isFalse(
        queryAndAssert<GrSelect>(element, '#force').classList.contains('force')
      );
    });

    test('modify and cancel restores original values', async () => {
      element.rule = {value: {}};
      element.editing = true;
      await element.updateComplete;
      assert.notEqual(
        getComputedStyle(queryAndAssert<GrButton>(element, '#removeBtn'))
          .display,
        'none'
      );
      assert.isNotOk(element.rule!.value!.modified);
      const actionBindValue = queryAndAssert<GrSelect>(element, '#action');
      actionBindValue.bindValue = 'DENY';
      assert.isTrue(element.rule!.value!.modified);
      element.editing = false;
      await element.updateComplete;
      assert.equal(
        getComputedStyle(queryAndAssert<GrButton>(element, '#removeBtn'))
          .display,
        'none'
      );
      assert.deepEqual(element.originalRuleValues, element.rule!.value);
      assert.equal(
        queryAndAssert<GrSelect>(element, '#action').bindValue,
        'ALLOW'
      );
      assert.isNotOk(element.rule!.value!.modified);
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const actionBindValue = queryAndAssert<GrSelect>(element, '#action');
      actionBindValue.bindValue = 'DENY';
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('all selects are disabled when not in edit mode', async () => {
      const selects = queryAll<HTMLSelectElement>(element, 'select');
      for (const select of selects) {
        assert.isTrue(select.disabled);
      }
      element.editing = true;
      await element.updateComplete;
      for (const select of selects) {
        assert.isFalse(select.disabled);
      }
    });

    test('remove rule and undo remove', async () => {
      element.editing = true;
      element.rule = {value: {action: 'ALLOW'}};
      await element.updateComplete;
      assert.isFalse(
        queryAndAssert<HTMLDivElement>(
          element,
          '#deletedContainer'
        ).classList.contains('deleted')
      );
      MockInteractions.tap(queryAndAssert<GrButton>(element, '#removeBtn'));
      await element.updateComplete;
      assert.isTrue(
        queryAndAssert<HTMLDivElement>(
          element,
          '#deletedContainer'
        ).classList.contains('deleted')
      );
      assert.isTrue(element.deleted);
      assert.isTrue(element.rule!.value!.deleted);

      MockInteractions.tap(queryAndAssert<GrButton>(element, '#undoRemoveBtn'));
      await element.updateComplete;
      assert.isFalse(element.deleted);
      assert.isNotOk(element.rule!.value!.deleted);
    });

    test('remove rule and cancel', async () => {
      element.editing = true;
      await element.updateComplete;
      assert.notEqual(
        getComputedStyle(queryAndAssert<GrButton>(element, '#removeBtn'))
          .display,
        'none'
      );
      assert.equal(
        getComputedStyle(
          queryAndAssert<HTMLDivElement>(element, '#deletedContainer')
        ).display,
        'none'
      );

      element.rule = {value: {action: 'ALLOW'}};
      await element.updateComplete;
      MockInteractions.tap(queryAndAssert<GrButton>(element, '#removeBtn'));
      await element.updateComplete;
      assert.notEqual(
        getComputedStyle(queryAndAssert<GrButton>(element, '#removeBtn'))
          .display,
        'none'
      );
      assert.notEqual(
        getComputedStyle(
          queryAndAssert<HTMLDivElement>(element, '#deletedContainer')
        ).display,
        'none'
      );
      assert.isTrue(element.deleted);
      assert.isTrue(element.rule!.value!.deleted);

      element.editing = false;
      await element.updateComplete;
      assert.isFalse(element.deleted);
      assert.isNotOk(element.rule!.value!.deleted);
      assert.isNotOk(element.rule!.value!.modified);

      assert.deepEqual(element.originalRuleValues, element.rule!.value);
      assert.equal(
        getComputedStyle(queryAndAssert<GrButton>(element, '#removeBtn'))
          .display,
        'none'
      );
      assert.equal(
        getComputedStyle(
          queryAndAssert<HTMLDivElement>(element, '#deletedContainer')
        ).display,
        'none'
      );
    });

    test('computeGroupPath', () => {
      const group = '123';
      assert.equal(element.computeGroupPath(group), '/admin/groups/123');
    });
  });

  suite('new edit rule', () => {
    setup(async () => {
      element.groupName = 'Group Name';
      element.permission = 'editTopicName' as AccessPermissionId;
      element.rule = {};
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.rule!.value!.added = true;
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule!.value!.modified);
      const expectedRuleValue = {
        action: 'ALLOW',
        force: false,
        added: true,
      };
      assert.deepEqual(element.rule!.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(
          queryAndAssert<GrSelect>(element, '#action').bindValue,
          expectedRuleValue.action
        );
        assert.equal(
          queryAndAssert<GrSelect>(element, '#force').bindValue,
          expectedRuleValue.action
        );
      });
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const forceBindValue = queryAndAssert<GrSelect>(element, '#force');
      forceBindValue.bindValue = 'true';
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('remove value', async () => {
      element.editing = true;
      const removeStub = sinon.stub();
      element.addEventListener('added-rule-removed', removeStub);
      MockInteractions.tap(queryAndAssert<GrButton>(element, '#removeBtn'));
      await element.updateComplete;
      assert.isTrue(removeStub.called);
    });
  });

  suite('already existing rule with labels', () => {
    setup(async () => {
      element.label = {
        values: [
          {value: -2, text: 'This shall not be merged'},
          {value: -1, text: 'I would prefer this is not merged as is'},
          {value: -0, text: 'No score'},
          {value: 1, text: 'Looks good to me, but someone else must approve'},
          {value: 2, text: 'Looks good to me, approved'},
        ],
      };
      element.groupName = 'Group Name';
      element.permission = 'label-Code-Review' as AccessPermissionId;
      element.rule = {
        value: {
          action: 'ALLOW',
          force: false,
          max: 2,
          min: -2,
        },
      };
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      assert.deepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('values are set correctly', () => {
      assert.equal(
        queryAndAssert<GrSelect>(element, '#action').bindValue,
        element.rule!.value!.action
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#labelMin').bindValue,
        element.rule!.value!.min
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#labelMax').bindValue,
        element.rule!.value!.max
      );
      assert.isFalse(
        queryAndAssert<GrSelect>(element, '#force').classList.contains('force')
      );
    });

    test('modify value', async () => {
      const removeStub = sinon.stub();
      element.addEventListener('added-rule-removed', removeStub);
      assert.isNotOk(element.rule!.value!.modified);
      const labelMinBindValue = queryAndAssert<GrSelect>(element, '#labelMin');
      labelMinBindValue.bindValue = 1;
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);
      assert.isFalse(removeStub.called);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });
  });

  suite('new rule with labels', () => {
    let setDefaultRuleValuesSpy: sinon.SinonSpy;

    setup(async () => {
      setDefaultRuleValuesSpy = sinon.spy(element, 'setDefaultRuleValues');
      element.label = {
        values: [
          {value: -2, text: 'This shall not be merged'},
          {value: -1, text: 'I would prefer this is not merged as is'},
          {value: -0, text: 'No score'},
          {value: 1, text: 'Looks good to me, but someone else must approve'},
          {value: 2, text: 'Looks good to me, approved'},
        ],
      };
      element.groupName = 'Group Name';
      element.permission = 'label-Code-Review' as AccessPermissionId;
      element.rule = {};
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.rule!.value!.added = true;
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule!.value!.modified);
      assert.isTrue(setDefaultRuleValuesSpy.called);

      const expectedRuleValue = {
        max: element.label!.values![element.label!.values.length - 1].value,
        min: element.label!.values![0].value,
        action: 'ALLOW',
        added: true,
      };
      assert.deepEqual(element.rule!.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(
          queryAndAssert<GrSelect>(element, '#action').bindValue,
          expectedRuleValue.action
        );
        assert.equal(
          queryAndAssert<GrSelect>(element, '#labelMin').bindValue,
          expectedRuleValue.min
        );
        assert.equal(
          queryAndAssert<GrSelect>(element, '#labelMax').bindValue,
          expectedRuleValue.max
        );
      });
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const labelMinBindValue = queryAndAssert<GrSelect>(element, '#labelMin');
      labelMinBindValue.bindValue = 1;
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });
  });

  suite('already existing push rule', () => {
    setup(async () => {
      element.groupName = 'Group Name';
      element.permission = 'push' as AccessPermissionId;
      element.rule = {
        value: {
          action: 'ALLOW',
          force: true,
        },
      };
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      assert.deepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('values are set correctly', () => {
      assert.isTrue(
        queryAndAssert<GrSelect>(element, '#force').classList.contains('force')
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#action').bindValue,
        element.rule!.value!.action
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#force').bindValue,
        element.rule!.value!.force
      );
      assert.isNotOk(query<GrSelect>(element, '#labelMin'));
      assert.isNotOk(query<GrSelect>(element, '#labelMax'));
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const actionBindValue = queryAndAssert<GrSelect>(element, '#action');
      actionBindValue.bindValue = false;
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });
  });

  suite('new push rule', async () => {
    setup(async () => {
      element.groupName = 'Group Name';
      element.permission = 'push' as AccessPermissionId;
      element.rule = {};
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.rule!.value!.added = true;
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule!.value!.modified);
      const expectedRuleValue = {
        action: 'ALLOW',
        force: false,
        added: true,
      };
      assert.deepEqual(element.rule!.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(
          queryAndAssert<GrSelect>(element, '#action').bindValue,
          expectedRuleValue.action
        );
        assert.equal(
          queryAndAssert<GrSelect>(element, '#force').bindValue,
          expectedRuleValue.action
        );
      });
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const forceBindValue = queryAndAssert<GrSelect>(element, '#force');
      forceBindValue.bindValue = true;
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });
  });

  suite('already existing edit rule', () => {
    setup(async () => {
      element.groupName = 'Group Name';
      element.permission = 'editTopicName' as AccessPermissionId;
      element.rule = {
        value: {
          action: 'ALLOW',
          force: true,
        },
      };
      element.section = 'refs/*';
      element.setupValues();
      await element.updateComplete;
      element.connectedCallback();
    });

    test('_ruleValues and originalRuleValues are set correctly', () => {
      assert.deepEqual(element.originalRuleValues, element.rule!.value);
    });

    test('values are set correctly', () => {
      assert.isTrue(
        queryAndAssert<GrSelect>(element, '#force').classList.contains('force')
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#action').bindValue,
        element.rule!.value!.action
      );
      assert.equal(
        queryAndAssert<GrSelect>(element, '#force').bindValue,
        element.rule!.value!.force
      );
      assert.isNotOk(query<GrSelect>(element, '#labelMin'));
      assert.isNotOk(query<GrSelect>(element, '#labelMax'));
    });

    test('modify value', async () => {
      assert.isNotOk(element.rule!.value!.modified);
      const actionBindValue = queryAndAssert<GrSelect>(element, '#action');
      actionBindValue.bindValue = false;
      await element.updateComplete;
      assert.isTrue(element.rule!.value!.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element.originalRuleValues, element.rule!.value);
    });
  });
});
