/**
 * @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 '../../../scripts/bundled-polymer.js';

import '@polymer/paper-toggle-button/paper-toggle-button.js';
import '../../../styles/gr-form-styles.js';
import '../../../styles/gr-menu-page-styles.js';
import '../../../styles/shared-styles.js';
import '../../shared/gr-autocomplete/gr-autocomplete.js';
import '../../shared/gr-button/gr-button.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-rule-editor/gr-rule-editor.js';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-permission_html.js';
import {AccessBehavior} from '../../../behaviors/gr-access-behavior/gr-access-behavior.js';

const MAX_AUTOCOMPLETE_RESULTS = 20;

const RANGE_NAMES = [
  'QUERY LIMIT',
  'BATCH CHANGES LIMIT',
];

/**
 * Fired when the permission has been modified or removed.
 *
 * @event access-modified
 */
/**
 * Fired when a permission that was previously added was removed.
 *
 * @event added-permission-removed
 * @extends Polymer.Element
 */
class GrPermission extends mixinBehaviors( [
  AccessBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-permission'; }

  static get properties() {
    return {
      repo: String,
      labels: Object,
      name: String,
      /** @type {?} */
      permission: {
        type: Object,
        observer: '_sortPermission',
        notify: true,
      },
      groups: Object,
      section: String,
      editing: {
        type: Boolean,
        value: false,
        observer: '_handleEditingChanged',
      },
      _label: {
        type: Object,
        computed: '_computeLabel(permission, labels)',
      },
      _groupFilter: String,
      _query: {
        type: Function,
        value() {
          return this._getGroupSuggestions.bind(this);
        },
      },
      _rules: Array,
      _groupsWithRules: Object,
      _deleted: {
        type: Boolean,
        value: false,
      },
      _originalExclusiveValue: Boolean,
    };
  }

  static get observers() {
    return [
      '_handleRulesChanged(_rules.splices)',
    ];
  }

  /** @override */
  created() {
    super.created();
    this.addEventListener('access-saved',
        () => this._handleAccessSaved());
  }

  /** @override */
  ready() {
    super.ready();
    this._setupValues();
  }

  _setupValues() {
    if (!this.permission) { return; }
    this._originalExclusiveValue = !!this.permission.value.exclusive;
    flush();
  }

  _handleAccessSaved() {
    // Set a new 'original' value to keep track of after the value has been
    // saved.
    this._setupValues();
  }

  _permissionIsOwnerOrGlobal(permissionId, section) {
    return permissionId === 'owner' || section === 'GLOBAL_CAPABILITIES';
  }

  _handleEditingChanged(editing, editingOld) {
    // Ignore when editing gets set initially.
    if (!editingOld) { return; }
    // Restore original values if no longer editing.
    if (!editing) {
      this._deleted = false;
      delete this.permission.value.deleted;
      this._groupFilter = '';
      this._rules = this._rules.filter(rule => !rule.value.added);
      for (const key of Object.keys(this.permission.value.rules)) {
        if (this.permission.value.rules[key].added) {
          delete this.permission.value.rules[key];
        }
      }

      // Restore exclusive bit to original.
      this.set(['permission', 'value', 'exclusive'],
          this._originalExclusiveValue);
    }
  }

  _handleAddedRuleRemoved(e) {
    const index = e.model.index;
    this._rules = this._rules.slice(0, index)
        .concat(this._rules.slice(index + 1, this._rules.length));
  }

  _handleValueChange() {
    this.permission.value.modified = true;
    // Allows overall access page to know a change has been made.
    this.dispatchEvent(
        new CustomEvent('access-modified', {bubbles: true, composed: true}));
  }

  _handleRemovePermission() {
    if (this.permission.value.added) {
      this.dispatchEvent(new CustomEvent(
          'added-permission-removed', {bubbles: true, composed: true}));
    }
    this._deleted = true;
    this.permission.value.deleted = true;
    this.dispatchEvent(
        new CustomEvent('access-modified', {bubbles: true, composed: true}));
  }

  _handleRulesChanged(changeRecord) {
    // Update the groups to exclude in the autocomplete.
    this._groupsWithRules = this._computeGroupsWithRules(this._rules);
  }

  _sortPermission(permission) {
    this._rules = this.toSortedArray(permission.value.rules);
  }

  _computeSectionClass(editing, deleted) {
    const classList = [];
    if (editing) {
      classList.push('editing');
    }
    if (deleted) {
      classList.push('deleted');
    }
    return classList.join(' ');
  }

  _handleUndoRemove() {
    this._deleted = false;
    delete this.permission.value.deleted;
  }

  _computeLabel(permission, labels) {
    if (!labels || !permission ||
        !permission.value || !permission.value.label) { return; }

    const labelName = permission.value.label;

    // It is possible to have a label name that is not included in the
    // 'labels' object. In this case, treat it like anything else.
    if (!labels[labelName]) { return; }
    const label = {
      name: labelName,
      values: this._computeLabelValues(labels[labelName].values),
    };
    return label;
  }

  _computeLabelValues(values) {
    const valuesArr = [];
    const keys = Object.keys(values)
        .sort((a, b) => parseInt(a, 10) - parseInt(b, 10));

    for (const key of keys) {
      let text = values[key];
      if (!text) { text = ''; }
      // The value from the server being used to choose which item is
      // selected is in integer form, so this must be converted.
      valuesArr.push({value: parseInt(key, 10), text});
    }
    return valuesArr;
  }

  /**
   * @param {!Array} rules
   * @return {!Object} Object with groups with rues as keys, and true as
   *    value.
   */
  _computeGroupsWithRules(rules) {
    const groups = {};
    for (const rule of rules) {
      groups[rule.id] = true;
    }
    return groups;
  }

  _computeGroupName(groups, groupId) {
    return groups && groups[groupId] && groups[groupId].name ?
      groups[groupId].name : groupId;
  }

  _getGroupSuggestions() {
    return this.$.restAPI.getSuggestedGroups(
        this._groupFilter,
        this.repo,
        MAX_AUTOCOMPLETE_RESULTS)
        .then(response => {
          const groups = [];
          for (const key in response) {
            if (!response.hasOwnProperty(key)) { continue; }
            groups.push({
              name: key,
              value: response[key],
            });
          }
          // Does not return groups in which we already have rules for.
          return groups
              .filter(group => !this._groupsWithRules[group.value.id]);
        });
  }

  /**
   * Handles adding a skeleton item to the dom-repeat.
   * gr-rule-editor handles setting the default values.
   */
  _handleAddRuleItem(e) {
    // The group id is encoded, but have to decode in order for the access
    // API to work as expected.
    const groupId = decodeURIComponent(e.detail.value.id)
        .replace(/\+/g, ' ');
    // We cannot use "this.set(...)" here, because groupId may contain dots,
    // and dots in property path names are totally unsupported by Polymer.
    // Apparently Polymer picks up this change anyway, otherwise we should
    // have looked at using MutableData:
    // https://polymer-library.polymer-project.org/2.0/docs/devguide/data-system#mutable-data
    this.permission.value.rules[groupId] = {};

    // Purposely don't recompute sorted array so that the newly added rule
    // is the last item of the array.
    this.push('_rules', {
      id: groupId,
    });

    // Add the new group name to the groups object so the name renders
    // correctly.
    if (this.groups && !this.groups[groupId]) {
      this.groups[groupId] = {name: this.$.groupAutocomplete.text};
    }

    // Wait for new rule to get value populated via gr-rule-editor, and then
    // add to permission values as well, so that the change gets propogated
    // back to the section. Since the rule is inside a dom-repeat, a flush
    // is needed.
    flush();
    const value = this._rules[this._rules.length - 1].value;
    value.added = true;
    // See comment above for why we cannot use "this.set(...)" here.
    this.permission.value.rules[groupId] = value;
    this.dispatchEvent(
        new CustomEvent('access-modified', {bubbles: true, composed: true}));
  }

  _computeHasRange(name) {
    if (!name) { return false; }

    return RANGE_NAMES.includes(name.toUpperCase());
  }

  /**
   * Work around a issue on iOS when clicking turns into double tap
   */
  _onTapExclusiveToggle(e) {
    e.preventDefault();
  }
}

customElements.define(GrPermission.is, GrPermission);
