// 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 GLOBAL_NAME = 'GLOBAL_CAPABILITIES';

  // The name that gets automatically input when a new reference is added.
  const NEW_NAME = 'refs/heads/*';
  const REFS_NAME = 'refs/';
  const ON_BEHALF_OF = '(On Behalf Of)';
  const LABEL = 'Label';

  Polymer({
    is: 'gr-access-section',

    properties: {
      capabilities: Object,
      /** @type {?} */
      section: {
        type: Object,
        notify: true,
        observer: '_sectionChanged',
      },
      groups: Object,
      labels: Object,
      editing: {
        type: Boolean,
        value: false,
      },
      _originalId: String,
      _editingRef: {
        type: Boolean,
        value: false,
      },
      _deleted: {
        type: Boolean,
        value: false,
      },
      _permissions: Array,
    },

    behaviors: [
      Gerrit.AccessBehavior,
    ],

    _sectionChanged(section) {
      this._permissions = this.toSortedArray(section.value.permissions);
      this._originalId = section.id;
    },

    _computePermissions(name, capabilities, labels) {
      let allPermissions;
      if (name === GLOBAL_NAME) {
        allPermissions = this.toSortedArray(capabilities);
      } else {
        const labelOptions = this._computeLabelOptions(labels);
        allPermissions = labelOptions.concat(
            this.toSortedArray(this.permissionValues));
      }
      return allPermissions.filter(permission => {
        return !this.section.value.permissions[permission.id];
      });
    },

    _computeLabelOptions(labels) {
      const labelOptions = [];
      for (const labelName of Object.keys(labels)) {
        labelOptions.push({
          id: 'label-' + labelName,
          value: {
            name: `${LABEL} ${labelName}`,
            id: 'label-' + labelName,
          },
        });
        labelOptions.push({
          id: 'labelAs-' + labelName,
          value: {
            name: `${LABEL} ${labelName} ${ON_BEHALF_OF}`,
            id: 'labelAs-' + labelName,
          },
        });
      }
      return labelOptions;
    },

    _computePermissionName(name, permission, permissionValues, capabilities) {
      if (name === GLOBAL_NAME) {
        return capabilities[permission.id].name;
      } else if (permissionValues[permission.id]) {
        return permissionValues[permission.id].name;
      } else if (permission.value.label) {
        let behalfOf = '';
        if (permission.id.startsWith('labelAs-')) {
          behalfOf = ON_BEHALF_OF;
        }
        return `${LABEL} ${permission.value.label}${behalfOf}`;
      }
    },

    _computeSectionName(name) {
      // When a new section is created, it doesn't yet have a ref. Set into
      // edit mode so that the user can input one.
      if (!name) {
        this._editingRef = true;
        // Needed for the title value. This is the same default as GWT.
        name = NEW_NAME;
        // Needed for the input field value.
        this.set('section.id', name);
      }
      if (name === GLOBAL_NAME) {
        return 'Global Capabilities';
      } else if (name.startsWith(REFS_NAME)) {
        return `Reference: ${name}`;
      }
      return name;
    },

    _handleRemoveReference() {
      this._deleted = true;
      this.set('section.value.deleted', true);
    },

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

    _handleEditReference() {
      this._editingRef = true;
    },

    _undoReferenceEdit() {
      this._editingRef = false;
      this.set('section.id', this._originalId);
    },

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

    _computeEditBtnClass(name) {
      return name === GLOBAL_NAME ? 'global' : '';
    },

    _handleAddPermission() {
      const value = this.$.permissionSelect.value;
      const permission = {
        id: value,
        value: {rules: {}},
      };

      // This is needed to update the 'label' property of the
      // 'label-<label-name>' permission.
      //
      // The value from the add permission dropdown will either be
      // label-<label-name> or labelAs-<labelName>.
      // But, the format of the API response is as such:
      // "permissions": {
      //  "label-Code-Review": {
      //    "label": "Code-Review",
      //    "rules": {...}
      //    }
      //  }
      // }
      // When we add a new item, we have to push the new permission in the same
      // format as the ones that have been returned by the API.
      if (value.startsWith('label')) {
        permission.value.label =
            value.replace('label-', '').replace('labelAs-', '');
      }
      // Add to the end of the array (used in dom-repeat) and also to the
      // section object that is two way bound with its parent element.
      this.push('_permissions', permission);
      this.set(['section.value.permissions', permission.id],
          permission.value);
    },
  });
})();