// 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',
      },
      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);
    },
  });
})();