/**
 * @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.
 */
(function() {
  'use strict';

  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
   */

  Polymer({
    is: 'gr-permission',

    properties: {
      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,
    },

    behaviors: [
      Gerrit.AccessBehavior,
      /**
       * Unused in this element, but called by other elements in tests
       * e.g gr-access-section_test.
       */
      Gerrit.FireBehavior,
    ],

    observers: [
      '_handleRulesChanged(_rules.splices)',
    ],

    listeners: {
      'access-saved': '_handleAccessSaved',
    },

    ready() {
      this._setupValues();
    },

    _setupValues() {
      if (!this.permission) { return; }
      this._originalExclusiveValue = !!this.permission.value.exclusive;
      Polymer.dom.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) => {
        return 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,
          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 => {
              return !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.
      Polymer.dom.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());
    },
  });
})();
