/**
 * @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 SUGGESTIONS_LIMIT = 15;
  const SAVING_ERROR_TEXT = 'Group may not exist, or you may not have '+
      'permission to add it';

  const URL_REGEX = '^(?:[a-z]+:)?//';

  Polymer({
    is: 'gr-group-members',

    properties: {
      groupId: Number,
      _groupMemberSearchId: String,
      _groupMemberSearchName: String,
      _includedGroupSearchId: String,
      _includedGroupSearchName: String,
      _loading: {
        type: Boolean,
        value: true,
      },
      _groupName: String,
      _groupMembers: Object,
      _includedGroups: Object,
      _itemName: String,
      _itemType: String,
      _queryMembers: {
        type: Function,
        value() {
          return this._getAccountSuggestions.bind(this);
        },
      },
      _queryIncludedGroup: {
        type: Function,
        value() {
          return this._getGroupSuggestions.bind(this);
        },
      },
      _groupOwner: {
        type: Boolean,
        value: false,
      },
      _isAdmin: {
        type: Boolean,
        value: false,
      },
    },

    behaviors: [
      Gerrit.BaseUrlBehavior,
      Gerrit.FireBehavior,
      Gerrit.URLEncodingBehavior,
    ],

    attached() {
      this._loadGroupDetails();

      this.fire('title-change', {title: 'Members'});
    },

    _loadGroupDetails() {
      if (!this.groupId) { return; }

      const promises = [];

      const errFn = response => {
        this.fire('page-error', {response});
      };

      return this.$.restAPI.getGroupConfig(this.groupId, errFn)
          .then(config => {
            if (!config || !config.name) { return Promise.resolve(); }

            this._groupName = config.name;

            promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
              this._isAdmin = isAdmin ? true : false;
            }));

            promises.push(this.$.restAPI.getIsGroupOwner(config.name)
                .then(isOwner => {
                  this._groupOwner = isOwner ? true : false;
                }));

            promises.push(this.$.restAPI.getGroupMembers(config.name).then(
                members => {
                  this._groupMembers = members;
                }));

            promises.push(this.$.restAPI.getIncludedGroup(config.name)
                .then(includedGroup => {
                  this._includedGroups = includedGroup;
                }));

            return Promise.all(promises).then(() => {
              this._loading = false;
            });
          });
    },

    _computeLoadingClass(loading) {
      return loading ? 'loading' : '';
    },

    _isLoading() {
      return this._loading || this._loading === undefined;
    },

    _computeGroupUrl(url) {
      if (!url) { return; }

      const r = new RegExp(URL_REGEX, 'i');
      if (r.test(url)) {
        return url;
      }

      // For GWT compatibility
      if (url.startsWith('#')) {
        return this.getBaseUrl() + url.slice(1);
      }
      return this.getBaseUrl() + url;
    },

    _handleSavingGroupMember() {
      return this.$.restAPI.saveGroupMembers(this._groupName,
          this._groupMemberSearchId).then(config => {
        if (!config) {
          return;
        }
        this.$.restAPI.getGroupMembers(this._groupName).then(members => {
          this._groupMembers = members;
        });
        this._groupMemberSearchName = '';
        this._groupMemberSearchId = '';
      });
    },

    _handleDeleteConfirm() {
      this.$.overlay.close();
      if (this._itemType === 'member') {
        return this.$.restAPI.deleteGroupMembers(this._groupName,
            this._itemId)
            .then(itemDeleted => {
              if (itemDeleted.status === 204) {
                this.$.restAPI.getGroupMembers(this._groupName)
                    .then(members => {
                      this._groupMembers = members;
                    });
              }
            });
      } else if (this._itemType === 'includedGroup') {
        return this.$.restAPI.deleteIncludedGroup(this._groupName,
            this._itemId)
            .then(itemDeleted => {
              if (itemDeleted.status === 204 || itemDeleted.status === 205) {
                this.$.restAPI.getIncludedGroup(this._groupName)
                    .then(includedGroup => {
                      this._includedGroups = includedGroup;
                    });
              }
            });
      }
    },

    _handleConfirmDialogCancel() {
      this.$.overlay.close();
    },

    _handleDeleteMember(e) {
      const id = e.model.get('item._account_id');
      const name = e.model.get('item.name');
      const username = e.model.get('item.username');
      const email = e.model.get('item.email');
      const item = username || name || email || id;
      if (!item) {
        return '';
      }
      this._itemName = item;
      this._itemId = id;
      this._itemType = 'member';
      this.$.overlay.open();
    },

    _handleSavingIncludedGroups() {
      return this.$.restAPI.saveIncludedGroup(this._groupName,
          this._includedGroupSearchId.replace(/\+/g, ' '), err => {
            if (err.status === 404) {
              this.dispatchEvent(new CustomEvent('show-alert', {
                detail: {message: SAVING_ERROR_TEXT},
                bubbles: true,
                composed: true,
              }));
              return err;
            }
            throw Error(err.statusText);
          })
          .then(config => {
            if (!config) {
              return;
            }
            this.$.restAPI.getIncludedGroup(this._groupName)
                .then(includedGroup => {
                  this._includedGroups = includedGroup;
                });
            this._includedGroupSearchName = '';
            this._includedGroupSearchId = '';
          });
    },

    _handleDeleteIncludedGroup(e) {
      const id = decodeURIComponent(e.model.get('item.id')).replace(/\+/g, ' ');
      const name = e.model.get('item.name');
      const item = name || id;
      if (!item) { return ''; }
      this._itemName = item;
      this._itemId = id;
      this._itemType = 'includedGroup';
      this.$.overlay.open();
    },

    _getAccountSuggestions(input) {
      if (input.length === 0) { return Promise.resolve([]); }
      return this.$.restAPI.getSuggestedAccounts(
          input, SUGGESTIONS_LIMIT).then(accounts => {
        const accountSuggestions = [];
        let nameAndEmail;
        if (!accounts) { return []; }
        for (const key in accounts) {
          if (!accounts.hasOwnProperty(key)) { continue; }
          if (accounts[key].email !== undefined) {
            nameAndEmail = accounts[key].name +
                  ' <' + accounts[key].email + '>';
          } else {
            nameAndEmail = accounts[key].name;
          }
          accountSuggestions.push({
            name: nameAndEmail,
            value: accounts[key]._account_id,
          });
        }
        return accountSuggestions;
      });
    },

    _getGroupSuggestions(input) {
      return this.$.restAPI.getSuggestedGroups(input)
          .then(response => {
            const groups = [];
            for (const key in response) {
              if (!response.hasOwnProperty(key)) { continue; }
              groups.push({
                name: key,
                value: decodeURIComponent(response[key].id),
              });
            }
            return groups;
          });
    },

    _computeHideItemClass(owner, admin) {
      return admin || owner ? '' : 'canModify';
    },
  });
})();
