/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');
var validator = require('utils/validator');
var stringUtils = require('utils/string_utils');
var hostsUtils = require('utils/hosts');

App.ServicesConfigView = Em.View.extend({
  templateName: require('templates/common/configs/services_config'),
  didInsertElement: function () {
    var controller = this.get('controller');
    controller.loadStep();
  }
});

App.ServiceConfigView = Em.View.extend({
  templateName: require('templates/common/configs/service_config'),
  isRestartMessageCollapsed: false,
  filter: '', //from template
  columns: [], //from template
  canEdit: true, // View is editable or read-only?
  supportsHostOverrides: function () {
    switch (this.get('controller.name')) {
      case 'wizardStep7Controller':
        return App.supports.hostOverridesInstaller;
      case 'mainServiceInfoConfigsController':
        return App.supports.hostOverrides;
      case 'mainHostServiceConfigsController':
        return App.supports.hostOverridesHost;
      default:
        return false;
    }
  }.property('controller.name'),
  toggleRestartMessageView: function () {
    this.$('.service-body').toggle('blind', 200);
    this.set('isRestartMessageCollapsed', !this.get('isRestartMessageCollapsed'));
  },
  didInsertElement: function () {
    if(this.get('isNotEditable') === true) {
      this.set('canEdit', false);
    }
    this.$('.service-body').hide();
    $(".restart-required-property").tooltip({html: true});
    $(".icon-lock").tooltip({placement: 'right'});
  }
});


App.ServiceConfigsByCategoryView = Ember.View.extend({

  classNames: ['accordion-group', 'common-config-category'],
  classNameBindings: ['category.name', 'isShowBlock::hidden'],

  content: null,
  category: null,
  service: null,
  canEdit: true, // View is editable or read-only?
  serviceConfigs: null, // General, Advanced, NameNode, SNameNode, DataNode, etc.
  // total number of
  // hosts (by
  // default,
  // cacheable )
  categoryConfigs: function () {
    return this.get('serviceConfigs').filterProperty('category', this.get('category.name')).filterProperty('isVisible', true);
  }.property('serviceConfigs.@each', 'categoryConfigsAll.@each.isVisible').cacheable(),

  /**
   * This method provides all the properties which apply
   * to this category, irrespective of visibility. This
   * is helpful in Oozie/Hive database configuration, where
   * MySQL etc. database options don't show up, because
   * they were not visible initially.
   */
  categoryConfigsAll: function () {
    return this.get('serviceConfigs').filterProperty('category', this.get('category.name'));
  }.property('serviceConfigs.@each').cacheable(),

  /**
   * Warn/prompt user to adjust Service props when changing user/groups in Misc
   * Is triggered when user ended editing text field
   */
  miscConfigChange: function (manuallyChangedProperty) {
    var changedProperty;
    if(manuallyChangedProperty.get("id")){
      changedProperty = [manuallyChangedProperty];
    }else{
      changedProperty = this.get("serviceConfigs").filterProperty("editDone", true);
    }

    if (changedProperty.length > 0) {
      changedProperty = changedProperty.objectAt(0);
    } else {
      return;
    }
    if (this.get('controller.selectedService.serviceName') == 'MISC') {
      var newValue = changedProperty.get("value");
      var stepConfigs = this.get("controller.stepConfigs");
      this.affectedProperties = [];
      var curConfigs = "";
      var affectedPropertyName = App.get('isHadoop2Stack') ? "dfs.permissions.superusergroup" : "dfs.permissions.supergroup";
      if (changedProperty.get("name") == "hdfs_user") {
        curConfigs = stepConfigs.findProperty("serviceName", "HDFS").get("configs");
        if (newValue != curConfigs.findProperty("name", affectedPropertyName).get("value")) {
          this.affectedProperties.push(
            {
              serviceName: "HDFS",
              propertyName: affectedPropertyName,
              propertyDisplayName: affectedPropertyName,
              newValue: newValue,
              curValue: curConfigs.findProperty("name", affectedPropertyName).get("value"),
              changedPropertyName: "hdfs_user"
            }
          );
        }
        if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"))) {
          this.affectedProperties.push(
            {
              serviceName: "HDFS",
              propertyName: "dfs.cluster.administrators",
              propertyDisplayName: "dfs.cluster.administrators",
              newValue: " " + $.trim(newValue),
              curValue: curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"),
              changedPropertyName: "hdfs_user"
            }
          );
        }
      } else if (changedProperty.get("name") == "hbase_user" && !App.get('isHadoop2Stack')) {
        curConfigs = stepConfigs.findProperty("serviceName", "HDFS").get("configs");
        if (newValue != curConfigs.findProperty("name", "dfs.block.local-path-access.user").get("value")) {
          this.affectedProperties.push(
            {
              serviceName: "HDFS",
              propertyName: "dfs.block.local-path-access.user",
              propertyDisplayName: "dfs.block.local-path-access.user",
              newValue: newValue,
              curValue: curConfigs.findProperty("name", "dfs.block.local-path-access.user").get("value"),
              changedPropertyName: "hbase_user"
            }
          );
        }
        var hbaseCurConfigs = stepConfigs.findProperty("serviceName", "HBASE").get("configs");
        if (newValue != hbaseCurConfigs.findProperty("name", "hbase.superuser").get("value")) {
          this.affectedProperties.push(
            {
              serviceName: "HBASE",
              propertyName: "hbase.superuser",
              propertyDisplayName: "hbase.superuser",
              newValue: newValue,
              curValue: hbaseCurConfigs.findProperty("name", "hbase.superuser").get("value"),
              changedPropertyName: "hbase_user"
            }
          );
        }
      } else if (changedProperty.get("name") == "user_group") {
        if (!((this.get("controller.selectedServiceNames").indexOf("MAPREDUCE") >= 0) || (this.get("controller.selectedServiceNames").indexOf("YARN") >= 0))) {
          return;
        }
        if(this.get("controller.selectedServiceNames").indexOf("MAPREDUCE") >= 0) {
          curConfigs = stepConfigs.findProperty("serviceName", "MAPREDUCE").get("configs");
          if (newValue != curConfigs.findProperty("name", "mapreduce.tasktracker.group").get("value")) {
            this.affectedProperties.push(
              {
                serviceName: "MAPREDUCE",
                propertyName: "mapreduce.tasktracker.group",
                propertyDisplayName: "mapreduce.tasktracker.group",
                newValue: newValue,
                curValue: curConfigs.findProperty("name", "mapreduce.tasktracker.group").get("value"),
                changedPropertyName: "user_group"
              }
            )
          }
          if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"))) {
            this.affectedProperties.push(
              {
                serviceName: "MAPREDUCE",
                propertyName: "mapreduce.cluster.administrators",
                propertyDisplayName: "mapreduce.cluster.administrators",
                newValue: " " + $.trim(newValue),
                curValue: curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"),
                changedPropertyName: "user_group"
              }
            );
          }
        }
        if(this.get("controller.selectedServiceNames").indexOf("MAPREDUCE2") >= 0) {
          curConfigs = stepConfigs.findProperty("serviceName", "MAPREDUCE2").get("configs");
          if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"))) {
            this.affectedProperties.push(
              {
                serviceName: "MAPREDUCE2",
                propertyName: "mapreduce.cluster.administrators",
                propertyDisplayName: "mapreduce.cluster.administrators",
                newValue: " " + $.trim(newValue),
                curValue: curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"),
                changedPropertyName: "user_group"
              }
            );
          }
        }
        if (this.get("controller.selectedServiceNames").indexOf("YARN") >= 0) {
        curConfigs = stepConfigs.findProperty("serviceName", "YARN").get("configs");
        if (newValue != curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value")) {
          this.affectedProperties.push(
            {
              serviceName: "YARN",
              propertyName: "yarn.nodemanager.linux-container-executor.group",
              propertyDisplayName: "yarn.nodemanager.linux-container-executor.group",
              newValue: newValue,
              curValue: curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value"),
              changedPropertyName: "user_group"
            }
          )
        }
        }
      }
      if (this.affectedProperties.length > 0 && !this.get("controller.miscModalVisible")) {
        this.newAffectedProperties = this.affectedProperties;
        var self = this;
        return App.ModalPopup.show({
          classNames: ['modal-690px-width'],
          showCloseButton: false,
          header: "Warning: you must also change these Service properties",
          onApply: function () {
            self.get("newAffectedProperties").forEach(function (item) {
              self.get("controller.stepConfigs").findProperty("serviceName", item.serviceName).get("configs")
                .findProperty("name", item.propertyName).set("value", item.newValue);
            });
            self.get("controller").set("miscModalVisible", false);
            this.hide();
          },
          onIgnore: function () {
            self.get("controller").set("miscModalVisible", false);
            this.hide();
          },
          onUndo: function () {
            var affected = self.get("newAffectedProperties").objectAt(0);
            self.get("controller.stepConfigs").findProperty("serviceName", "MISC").get("configs")
              .findProperty("name", affected.changedPropertyName).set("value", $.trim(affected.curValue));
            self.get("controller").set("miscModalVisible", false);
            this.hide();
          },
          footerClass: Ember.View.extend({
            classNames: ['modal-footer'],
            template: Ember.Handlebars.compile([
              '<div class="pull-right">',
              '<button class="btn" {{action onUndo target="view.parentView"}}>Cancel</button>',
              '<button class="btn btn-warning" {{action onIgnore target="view.parentView"}}>Ignore</button>',
              '<button class="btn btn-success" {{action onApply target="view.parentView"}}>Apply</button>',
              '</div>'
            ].join(''))
          }),
          bodyClass: Ember.View.extend({
            templateName: require('templates/common/configs/propertyDependence'),
            controller: this,
            propertyChange: self.get("newAffectedProperties"),
            didInsertElement: function () {
              self.get("controller").set("miscModalVisible", true);
            }
          })
        });
      }
    }
  }.observes('categoryConfigs.@each.editDone'),

  /**
   * When the view is in read-only mode, it marks
   * the properties as read-only.
   */
  updateReadOnlyFlags: function () {
    var configs = this.get('serviceConfigs');
    var canEdit = this.get('canEdit');
    if (!canEdit && configs) {
      configs.forEach(function(c){
        c.set('isEditable', false);
        var overrides = c.get('overrides');
        if (overrides!=null) {
          overrides.setEach('isEditable', false);
        }
      });
    }
  },

  /**
   * Filtered <code>categoryConfigs</code> array. Used to show filtered result
   */
  filteredCategoryConfigs: function () {
    var filter = this.get('parentView.filter').toLowerCase();
    //var isOnlyModified = this.get('parentView.columns').length && this.get('parentView.columns')[1].get('selected');
    var isOnlyOverridden = this.get('parentView.columns').length && this.get('parentView.columns')[0].get('selected');
    //var isOnlyRestartRequired = this.get('parentView.columns').length && this.get('parentView.columns')[2].get('selected');
    var filteredResult = this.get('categoryConfigs').filter(function (config) {

     /* if (isOnlyModified && !config.get('isNotDefaultValue')) {
        return false;
      }

      if (isOnlyRestartRequired && !config.get('isRestartRequired')) {
        return false;
      }*/

      if (isOnlyOverridden && !config.get('isOverridden')) {
        return false;
      }

      var searchString = config.get('defaultValue') + config.get('description') +
        config.get('displayName') + config.get('name');

     if (config.get('overrides')) {
       config.get('overrides').forEach(function(overriddenConf){
         searchString += overriddenConf.get('value') + overriddenConf.get('group.name');
       });
     }


      return searchString.toLowerCase().indexOf(filter) > -1;
    });
    filteredResult = this.sortByIndex(filteredResult);
    return filteredResult;
  }.property('categoryConfigs', 'parentView.filter', 'parentView.columns.@each.selected'),

  /**
   * sort configs in current category by index
   * @param configs
   * @return {*}
   */
  sortByIndex: function (configs) {
    var sortedConfigs = [];
    var unSorted = [];
    if (!configs.someProperty('index')) {
      return configs;
    }
    configs.forEach(function (config) {
      var index = config.get('index');
      if ((index !== null) && isFinite(index)) {
        sortedConfigs[index] ? sortedConfigs.splice(index, 0, config) : sortedConfigs[index] = config;
      } else {
        unSorted.push(config);
      }
    });
    // remove undefined elements from array
    sortedConfigs = sortedConfigs.filter(function (config) {
      if (config !== undefined) return true;
    });
    return sortedConfigs.concat(unSorted);
  },
  /**
   * Onclick handler for Config Group Header. Used to show/hide block
   */
  onToggleBlock: function () {
    this.$('.accordion-body').toggle('blind', 500);
    this.set('category.isCollapsed', !this.get('category.isCollapsed'));
  },

  /**
   * Should we show config group or not
   */
  isShowBlock: function () {
    return this.get('category.canAddProperty') || this.get('filteredCategoryConfigs').length > 0;
  }.property('category.canAddProperty', 'filteredCategoryConfigs.length'),

  didInsertElement: function () {
    var isCollapsed = (this.get('category.name').indexOf('Advanced') != -1);
    var self = this;
    this.set('category.isCollapsed', isCollapsed);
    if (isCollapsed) {
      this.$('.accordion-body').hide();
    }
    this.updateReadOnlyFlags();
    Em.run.next(function() {
      self.updateReadOnlyFlags();
    });
  },
  childView: App.ServiceConfigsOverridesView,
  changeFlag: Ember.Object.create({
    val: 1
  }),
  isOneOfAdvancedSections: function () {
    var category = this.get('category');
    return category.indexOf("Advanced") != -1;
  },
  showAddPropertyWindow: function (event) {
    var configsOfFile = this.get('service.configs').filterProperty('filename', this.get('category.siteFileName'));
    var self =this;
    var serviceConfigObj = Ember.Object.create({
      name: '',
      value: '',
      defaultValue: null,
      filename: '',
      isUserProperty: true,
      isKeyError: false,
      errorMessage: "",
      observeAddPropertyValue: function () {
        var name = this.get('name');
        if (name.trim() != "") {
          if (validator.isValidConfigKey(name)) {
            var configMappingProperty = App.config.get('configMapping').all().filterProperty('filename',self.get('category.siteFileName')).findProperty('name', name);
            if ((configMappingProperty == null) && (!configsOfFile.findProperty('name', name))) {
              this.set("isKeyError", false);
              this.set("errorMessage", "");
            } else {
              this.set("isKeyError", true);
              this.set("errorMessage", Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey'));
            }
          } else {
            this.set("isKeyError", true);
            this.set("errorMessage", Em.I18n.t('form.validator.configKey'));
          }
        } else {
          this.set("isKeyError", true);
          this.set("errorMessage", Em.I18n.t('services.service.config.addPropertyWindow.errorMessage'));
        }
      }.observes("name")
    });

    var category = this.get('category');
    serviceConfigObj.displayType = "advanced";
    serviceConfigObj.category = category.get('name');

    var serviceName = this.get('service.serviceName');
    var serviceConfigsMetaData = App.config.get('preDefinedServiceConfigs');
    var serviceConfigMetaData = serviceConfigsMetaData.findProperty('serviceName', serviceName);
    var categoryMetaData = serviceConfigMetaData == null ? null : serviceConfigMetaData.configCategories.findProperty('name', category.get('name'));
    if (categoryMetaData != null) {
      serviceConfigObj.filename = categoryMetaData.siteFileName;
    }

    var self = this;
    App.ModalPopup.show({
      // classNames: ['big-modal'],
      classNames: [ 'sixty-percent-width-modal'],
      header: "Add Property",
      primary: 'Add',
      secondary: 'Cancel',
      onPrimary: function () {
        serviceConfigObj.observeAddPropertyValue();
        /**
         * For the first entrance use this if (serviceConfigObj.name.trim() != "")
         */
        if (!serviceConfigObj.isKeyError) {
          serviceConfigObj.displayName = serviceConfigObj.name;
          serviceConfigObj.id = 'site property';
          serviceConfigObj.serviceName = serviceName;
          serviceConfigObj.displayType = stringUtils.isSingleLine(serviceConfigObj.get('value')) ? 'advanced' : 'multiLine';
          var serviceConfigProperty = App.ServiceConfigProperty.create(serviceConfigObj);
          self.get('controller.secureConfigs').filterProperty('filename', self.get('category.siteFileName')).forEach(function (_secureConfig) {
            if (_secureConfig.name === serviceConfigProperty.get('name')) {
              serviceConfigProperty.set('isSecureConfig', true);
            }
          }, this);
          self.get('serviceConfigs').pushObject(serviceConfigProperty);
          this.hide();
        }
      },
      onSecondary: function () {
        this.hide();
      },
      bodyClass: Ember.View.extend({
        templateName: require('templates/common/configs/addPropertyWindow'),
        controllerBinding: 'App.router.mainServiceInfoConfigsController',
        serviceConfigProperty: serviceConfigObj
      })
    });

  },

  /**
   * Removes the top-level property from list of properties.
   * Should be only called on user properties.
   */
  removeProperty: function (event) {
    var serviceConfigProperty = event.contexts[0];
    this.get('serviceConfigs').removeObject(serviceConfigProperty);
  },

  /**
   * Restores given property's value to be its default value.
   * Does not update if there is no default value.
   */
  doRestoreDefaultValue: function (event) {
    var serviceConfigProperty = event.contexts[0];
    var value = serviceConfigProperty.get('value');
    var dValue = serviceConfigProperty.get('defaultValue');
    if (dValue != null) {
      if (serviceConfigProperty.get('displayType') === 'password') {
        serviceConfigProperty.set('retypedPassword', dValue);
      }
      serviceConfigProperty.set('value', dValue);
    }
    this.miscConfigChange(serviceConfigProperty);
  },

  createOverrideProperty: function (event) {
    var serviceConfigProperty = event.contexts[0];
    var serviceConfigController = this.get('controller');
    var selectedConfigGroup = serviceConfigController.get('selectedConfigGroup');
    if (selectedConfigGroup.get('isDefault')) {
      // Launch dialog to pick/create Config-group
      App.config.launchConfigGroupSelectionCreationDialog(this.get('service.serviceName'),
          serviceConfigController.get('configGroups'), serviceConfigController.get('allConfigGroupsNames'), serviceConfigProperty, function (selectedGroupInPopup) {
            console.log("launchConfigGroupSelectionCreationDialog(): Selected/Created:", selectedGroupInPopup);
            if (selectedGroupInPopup) {
              serviceConfigController.set('overrideToAdd', serviceConfigProperty);
              serviceConfigController.set('selectedConfigGroup', selectedGroupInPopup);
            }
          });
    } else {
      serviceConfigController.addOverrideProperty(serviceConfigProperty);
    }
  },

  showOverrideWindow: function (event) {
    // argument 1
    var serviceConfigProperty = event.contexts[0];
    var parentServiceConfigProperty = serviceConfigProperty.get('parentSCP');
    var alreadyOverriddenHosts = [];
    parentServiceConfigProperty.get('overrides').forEach(function (override) {
      if (override != null && override != serviceConfigProperty && override.get('selectedHostOptions') != null) {
        alreadyOverriddenHosts = alreadyOverriddenHosts.concat(override.get('selectedHostOptions'))
      }
    });
    var selectedHosts = serviceConfigProperty.get('selectedHostOptions');
    /**
     * Get all the hosts available for selection. Since data is dependent on
     * controller, we ask it, instead of doing regular Ember's App.Host.find().
     * This should be an array of App.Host.
     */
    var allHosts = this.get('controller.getAllHosts');
    var availableHosts = Ember.A([]);
    allHosts.forEach(function (host) {
      var hostId = host.get('id');
      if (alreadyOverriddenHosts.indexOf(hostId) < 0) {
        availableHosts.pushObject(Ember.Object.create({
          selected: selectedHosts.indexOf(hostId) > -1,
          host: host
        }));
      }
    });
    /**
     * From the currently selected service we want the service-components.
     * We only need an array of objects which have the 'componentName' and
     * 'displayName' properties. Since each controller has its own objects,
     * we ask for a normalized array back.
     */
    var validComponents = this.get('controller.getCurrentServiceComponents');
    hostsUtils.launchHostsSelectionDialog(availableHosts, selectedHosts,
        false, validComponents, function(newSelectedHosts){
      if (newSelectedHosts!=null) {
        serviceConfigProperty.set('selectedHostOptions', newSelectedHosts);
        serviceConfigProperty.validate();
      } else {
        // Dialog cancelled
        // If property has no hosts already, then remove it from the parent.
        var hostCount = serviceConfigProperty.get('selectedHostOptions.length');
        if (hostCount < 1) {
          var parentSCP = serviceConfigProperty.get('parentSCP');
          var overrides = parentSCP.get('overrides');
          overrides.removeObject(serviceConfigProperty);
        }
      }
    });
  }
});

App.ServiceConfigTab = Ember.View.extend({

  tagName: 'li',

  selectService: function (event) {
    this.set('controller.selectedService', event.context);
  },

  didInsertElement: function () {
    var serviceName = this.get('controller.selectedService.serviceName');
    this.$('a[href="#' + serviceName + '"]').tab('show');
  }
});

/**
 * custom view for capacity scheduler category
 * @type {*}
 */
App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
  templateName: require('templates/common/configs/capacity_scheduler'),
  category: null,
  service: null,
  serviceConfigs: null,
  customConfigs: function(){
    return App.config.get('preDefinedCustomConfigs');
  }.property('App.config.preDefinedCustomConfigs'),
  /**
   * configs filtered by capacity-scheduler category
   */
  categoryConfigs: function () {
    return this.get('serviceConfigs').filterProperty('category', this.get('category.name'));
  }.property('queueObserver', 'serviceConfigs.@each'),
  /**
   * rewrote method to avoid incompatibility with parent
   */
  filteredCategoryConfigs: function () {
    return this.get('categoryConfigs');
  }.property(),
  advancedConfigs: function () {
    return this.get('categoryConfigs').filterProperty('isQueue', undefined) || [];
  }.property('categoryConfigs.@each'),
  didInsertElement: function () {
    this._super();
    this.createEmptyQueue(this.get('customConfigs').filterProperty('isQueue'));
  },
  //list of fields which will be populated by default in a new queue
  fieldsToPopulate: function(){
    if(App.get('isHadoop2Stack')){
      return ["yarn.scheduler.capacity.root.<queue-name>.user-limit-factor",
      "yarn.scheduler.capacity.root.<queue-name>.state"];
    }
    return [
      "mapred.capacity-scheduler.queue.<queue-name>.minimum-user-limit-percent",
      "mapred.capacity-scheduler.queue.<queue-name>.user-limit-factor",
      "mapred.capacity-scheduler.queue.<queue-name>.supports-priority",
      "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks",
      "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks-per-user",
      "mapred.capacity-scheduler.queue.<queue-name>.init-accept-jobs-factor"
    ];
  }.property('App.isHadoop2Stack'),
  /**
   * create empty queue
   * take some queue then copy it and set all config values to null
   * @param customConfigs
   */
  createEmptyQueue: function (customConfigs) {
    var emptyQueue = {
      name: '<queue-name>',
      configs: []
    };
    var fieldsToPopulate = this.get('fieldsToPopulate');
    customConfigs.forEach(function (config) {
      var newConfig = $.extend({}, config);
      if (fieldsToPopulate.contains(config.name)) {
        newConfig.value = config.defaultValue;
      }
      newConfig = App.ServiceConfigProperty.create(newConfig);
      newConfig.validate();
      emptyQueue.configs.push(newConfig);
    });
    this.set('emptyQueue', emptyQueue);
  },
  deriveQueueNames: function(configs){
    var queueNames = [];
    configs.mapProperty('name').forEach(function(name){
      var queueName;
      if(App.get('isHadoop2Stack')){
        queueName = /^yarn\.scheduler\.capacity\.root\.(.*?)\./.exec(name);
      } else {
        queueName = /^mapred\.capacity-scheduler\.queue\.(.*?)\./.exec(name);
      }
      if(queueName){
        queueNames.push(queueName[1]);
      }
    });
    return queueNames.uniq();
  },
  queues: function(){
    var configs = this.get('categoryConfigs').filterProperty('isQueue', true);
    var queueNames = this.deriveQueueNames(configs);
    var queues = [];

    queueNames.forEach(function(queueName){
      queues.push({
        name: queueName,
        color: this.generateColor(queueName),
        configs: this.groupConfigsByQueue(queueName, configs)
      })
    }, this);
    return queues;
  }.property('queueObserver'),
  /**
   * group configs by queue
   * @param queueName
   * @param configs
   */
  groupConfigsByQueue: function (queueName, configs) {
    var customConfigs = [];
    var queue = [];
    this.get('customConfigs').forEach(function(_config){
      var copy = $.extend({}, _config);
      copy.name = _config.name.replace('<queue-name>', queueName);
      customConfigs.push(copy);
    });
    configs.forEach(function (config) {
      var customConfig = customConfigs.findProperty('name', config.get('name'));
      if (customConfig) {
        config.set('description', customConfig.description);
        config.set('displayName', customConfig.displayName);
        config.set('isRequired', customConfig.isRequired);
        config.set('unit', customConfig.unit);
        config.set('displayType', customConfig.displayType);
        config.set('valueRange', customConfig.valueRange);
        config.set('isVisible', customConfig.isVisible);
        config.set('inTable', customConfig.inTable);
        config.set('index', customConfig.index);
        queue.push(config);
      }
    });
    if(queue.length < customConfigs.length){
      this.addMissingProperties(queue, customConfigs);
    }
    return queue;
  },
  /**
   * add missing properties to queue when they don't come from server
   * @param queue
   * @param customConfigs
   */
  addMissingProperties: function(queue, customConfigs){
    customConfigs.forEach(function(_config){
      var serviceConfigProperty;
      if(!queue.someProperty('name', _config.name)){
        _config.value = _config.defaultValue;
        serviceConfigProperty = App.ServiceConfigProperty.create(_config);
        serviceConfigProperty.validate();
        queue.push(serviceConfigProperty);
      }
    }, this);
  },
  /**
   * convert queues to table content
   */
  tableContent: function () {
    var result = [];
    this.get('queues').forEach(function (queue) {
      var usersAndGroups = queue.configs.findProperty('name', this.getUserAndGroupNames(queue.name)[0]).get('value');
      usersAndGroups = (usersAndGroups) ? usersAndGroups.split(' ') : [''];
      if (usersAndGroups.length == 1) {
        usersAndGroups.push('');
      }
      var queueObject = {
        name: queue.name,
        color: 'background-color:' + queue.color + ';',
        configs: this.sortByIndex(queue.configs.filterProperty('inTable'))
      };
      //push acl_submit_jobs users
      queueObject.configs.unshift({
        value: usersAndGroups[1],
        inTable: true,
        displayName: Em.I18n.t('common.users')
      });
      //push acl_submit_jobs groups
      queueObject.configs.unshift({
        value: usersAndGroups[0],
        inTable: true,
        displayName: Em.I18n.t('services.mapReduce.config.queue.groups')
      });
      result.push(queueObject);
    }, this);
    return result;
  }.property('queues'),
  /**
   * create headers depending on existed properties in queue
   */
  tableHeaders: function(){
    var headers = [
      Em.I18n.t('services.mapReduce.config.queue.name')
    ];
    return (this.get('tableContent').length) ?
      headers.concat(this.get('tableContent').objectAt(0).configs.filterProperty('inTable').mapProperty('displayName')):
      headers;
  }.property('tableContent'),
  queueObserver: null,
  /**
   * uses as template for adding new queue
   */
  emptyQueue: {},
  /**
   * get capacities sum of queues except of current
   * @param queueName
   * @return {Number}
   */
  getQueuesCapacitySum: function(queueName){
    var capacitySum = 0;
    this.get('queues').filter(function(queue){
      return queue.name !== queueName;
    }).forEach(function(queue){
        capacitySum = capacitySum + window.parseInt(queue.configs.find(function(config){
          return config.get('name').substr(-9, 9) === '.capacity';
        }).get('value'));
      });
    return capacitySum;
  },
  /**
   * get names of configs, for users and groups, which have different names in HDP1 and HDP2
   * @param queueName
   * @return {Array}
   */
  getUserAndGroupNames: function(queueName){
    queueName = queueName || '<queue-name>';
    if(App.config.get('isHDP2')){
      return ['yarn.scheduler.capacity.root.' + queueName + '.acl_submit_jobs',
        'yarn.scheduler.capacity.root.' + queueName + '.acl_administer_jobs']
    }
    return ['mapred.queue.' + queueName + '.acl-submit-job',
      'mapred.queue.' + queueName + '.acl-administer-jobs']
  },
  generateColor: function (str) {
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
      hash = str.charCodeAt(i) + ((hash << 5) - hash);
    }
    return '#' + Number(Math.abs(hash)).toString(16).concat('00000').substr(0, 6);
  },
  /**
   * add new queue
   * add created configs to serviceConfigs with current queue name
   * @param queue
   */
  addQueue: function (queue) {
    var serviceConfigs = this.get('serviceConfigs');
    var admin = [];
    var submit = [];
    var submitConfig;
    var adminConfig;
    queue.name = queue.configs.findProperty('name', 'queueName').get('value');
    queue.configs.forEach(function (config) {
      var adminName = this.getUserAndGroupNames()[1];
      var submitName = this.getUserAndGroupNames()[0];
      if(config.name == adminName){
        if (config.type == 'USERS') {
          admin[0] = config.value;
        }
        if (config.type == 'GROUPS') {
          admin[1] = config.value;
        }
        if (config.isQueue) {
          adminConfig = config;
        }
      }
      if(config.name == submitName){
        if (config.type == 'USERS') {
          submit[0] = config.value;
        }
        if (config.type == 'GROUPS') {
          submit[1] = config.value;
        }
        if (config.isQueue) {
          submitConfig = config;
        }
      }
      config.set('name', config.get('name').replace('<queue-name>', queue.name));
      config.set('value', config.get('value').toString());
      if (config.isQueue) {
        serviceConfigs.push(config);
      }
    }, this);
    adminConfig.set('value', admin.join(' '));
    submitConfig.set('value', submit.join(' '));
    this.set('queueObserver', new Date().getTime());
  },
  /**
   * delete queue
   * delete configs from serviceConfigs which have current queue name
   * @param queue
   */
  deleteQueue: function (queue) {
    var serviceConfigs = this.get('serviceConfigs');
    var configNames = queue.configs.filterProperty('isQueue').mapProperty('name');
    for (var i = 0, l = serviceConfigs.length; i < l; i++) {
      if (configNames.contains(serviceConfigs[i].name)) {
        serviceConfigs.splice(i, 1);
        l--;
        i--;
      }
    }
    this.set('queueObserver', new Date().getTime());
  },
  /**
   * save changes that was made to queue
   * edit configs from serviceConfigs which have current queue name
   * @param queue
   */
  editQueue: function (queue) {
    var serviceConfigs = this.get('serviceConfigs');
    var configNames = queue.configs.filterProperty('isQueue').mapProperty('name');
    serviceConfigs.forEach(function (_config) {
      var configName = _config.get('name');
      var admin = [];
      var submit = [];
      //comparison executes including 'queue.<queue-name>' to avoid false matches
      var queueNamePrefix = App.config.get('isHDP2') ? 'root.' : 'queue.';
      if (configNames.contains(_config.get('name'))) {
        if(configName == this.getUserAndGroupNames(queue.name)[0]){
          submit = queue.configs.filterProperty('name', configName);
          submit = submit.findProperty('type', 'USERS').get('value') + ' ' + submit.findProperty('type', 'GROUPS').get('value');
          _config.set('value', submit);
        } else if(configName == this.getUserAndGroupNames(queue.name)[1]){
          admin = queue.configs.filterProperty('name', configName);
          admin = admin.findProperty('type', 'USERS').get('value') + ' ' + admin.findProperty('type', 'GROUPS').get('value');
          _config.set('value', admin);
        } else {
          _config.set('value', queue.configs.findProperty('name', _config.get('name')).get('value').toString());
        }
        _config.set('name', configName.replace(queueNamePrefix + queue.name, queueNamePrefix + queue.configs.findProperty('name', 'queueName').get('value')));
      }
    }, this);
    this.set('queueObserver', new Date().getTime());
  },
  pieChart: App.ChartPieView.extend({
    w: 200,
    h: 200,
    queues: null,
    didInsertElement: function () {
      this.update();
    },
    data: [{"label":"default", "value":100}],
    update: function () {
      var self = this;
      var data = [];
      var queues = this.get('queues');
      var capacitiesSum = 0;
      queues.forEach(function (queue) {
        var value = window.parseInt(queue.configs.find(function(_config){
          return _config.get('name').substr(-9, 9) === '.capacity';
        }).get('value'));
        data.push({
          label: queue.name,
          value: value,
          color: queue.color
        })
      });

      data.mapProperty('value').forEach(function (capacity) {
        capacitiesSum += capacity;
      });
      if (capacitiesSum < 100) {
        data.push({
          label: Em.I18n.t('common.empty'),
          value: (100 - capacitiesSum),
          color: 'transparent',
          isEmpty: true
        })
      }
      $(d3.select(this.get('selector'))[0]).children().remove();
      this.set('data', data);
      this.set('palette', new Rickshaw.Color.Palette({
        scheme: data.mapProperty('color')
      }));
      this.appendSvg();

      this.get('arcs')
        .on("click",function (d, i) {
          var event = {context: d.data.label};
          if (d.data.isEmpty !== true) self.get('parentView').queuePopup(event);
        }).on('mouseover', function (d, i) {
          var position = d3.svg.mouse(this);
          var label = $('#section_label');
          label.css('left', position[0] + 100);
          label.css('top', position[1] + 100);
          label.text(d.data.label);
          label.show();
        })
        .on('mouseout', function (d, i) {
          $('#section_label').hide();
        })

    }.observes('queues'),
    donut: d3.layout.pie().sort(null).value(function (d) {
      return d.value;
    })
  }),
  /**
   * open popup with chosen queue
   * @param event
   */
  queuePopup: function (event) {
    //if queueName was handed that means "Edit" mode, otherwise "Add" mode
    var queueName = event.context || null;
    var self = this;
    App.ModalPopup.show({
      didInsertElement: function () {
        if (queueName) {
          this.set('header', Em.I18n.t('services.mapReduce.config.editQueue'));
          this.set('secondary', Em.I18n.t('common.save'));
          if (self.get('queues').length > 1 && self.get('canEdit')) {
            this.set('delete', Em.I18n.t('common.delete'));
          }
        }
      },
      header: Em.I18n.t('services.mapReduce.config.addQueue'),
      secondary: Em.I18n.t('common.add'),
      primary: Em.I18n.t('common.cancel'),
      delete: null,
      isError: function () {
        if (!self.get('canEdit')) {
          return true;
        }
        var content = this.get('content');
        var configs = content.configs.filter(function (config) {
          return !(config.name == self.getUserAndGroupNames(content.name)[0] ||
            config.name == self.getUserAndGroupNames(content.name)[1] &&
              config.isQueue);
        });
        return configs.someProperty('isValid', false);
      }.property('content.configs.@each.isValid'),
      onDelete: function () {
        var view = this;
        App.ModalPopup.show({
          header: Em.I18n.t('popup.confirmation.commonHeader'),
          body: Em.I18n.t('hosts.delete.popup.body'),
          primary: Em.I18n.t('yes'),
          onPrimary: function () {
            self.deleteQueue(view.get('content'));
            view.hide();
            this.hide();
          }
        });
      },
      onSecondary: function () {
        if (queueName) {
          self.editQueue(this.get('content'));
        } else {
          self.addQueue(this.get('content'));
        }
        this.hide();
      },
      /**
       * Queue properties order:
       * 1. Queue Name
       * 2. Capacity
       * 3. Max Capacity
       * 4. Users
       * 5. Groups
       * 6. Admin Users
       * 7. Admin Groups
       * 8. Support Priority
       * ...
       */
      content: function () {
        var content = (queueName) ? self.get('queues').findProperty('name', queueName) : self.get('emptyQueue');
        var configs = [];
        // copy of queue configs
        content.configs.forEach(function (config, index) {
          if(config.get('name').substr(-9, 9) === '.capacity') {
            //added validation function for capacity property
            config.reopen({
              validate: function () {
                var value = this.get('value');
                var isError = false;
                var capacitySum = self.getQueuesCapacitySum(content.name);
                if (value == '') {
                  if (this.get('isRequired')) {
                    this.set('errorMessage', 'This is required');
                    isError = true;
                  } else {
                    return;
                  }
                }
                if (!isError) {
                  if (!validator.isValidInt(value)) {
                    this.set('errorMessage', 'Must contain digits only');
                    isError = true;
                  }
                }
                if (!isError) {
                  if ((capacitySum + parseInt(value)) > 100) {
                    isError = true;
                    this.set('errorMessage', 'The sum of capacities more than 100');
                  }
                  if (!isError) {
                    this.set('errorMessage', '');
                  }
                }
              }.observes('value')
            });
          }
          if (config.name == 'mapred.capacity-scheduler.queue.' + content.name + '.supports-priority') {
            if (config.get('value') == 'true' || config.get('value') === true) {
              config.set('value', true);
            } else {
              config.set('value', false);
            }
          }
          if(config.name === 'yarn.scheduler.capacity.root.' + content.name + '.state'){
            config.reopen({
              validate: function(){
                var value = this.get('value');
                this._super();
                if(!this.get('errorMessage')){
                  if(!(value === 'STOPPED' || value === 'RUNNING')){
                    this.set('errorMessage', 'State value should be RUNNING or STOPPED');
                  }
                }
              }.observes('value')
            })
          }
          configs[index] = App.ServiceConfigProperty.create(config);
        });
        content = {
          name: content.name,
          configs: configs
        };
        content = this.insertExtraConfigs(content);
        content.configs = self.sortByIndex(content.configs);
        return content;
      }.property(),
      footerClass: Ember.View.extend({
        classNames: ['modal-footer', 'host-checks-update'],
        template: Ember.Handlebars.compile([
          '{{#if view.parentView.delete}}<div class="pull-left">',
          '<button class="btn btn-danger" {{action onDelete target="view.parentView"}}>',
          '{{view.parentView.delete}}</button></div>{{/if}}',
          '<p class="pull-right">',
          '{{#if view.parentView.primary}}<button type="button" class="btn" {{action onPrimary target="view.parentView"}}>',
          '{{view.parentView.primary}}</button>{{/if}}',
          '{{#if view.parentView.secondary}}',
          '<button type="button" {{bindAttr disabled="view.parentView.isError"}} class="btn btn-success" {{action onSecondary target="view.parentView"}}>',
          '{{view.parentView.secondary}}</button>{{/if}}',
          '</p>'
        ].join(''))
      }),
      bodyClass: Ember.View.extend({
        template: Ember.Handlebars.compile([
          '<form class="form-horizontal pre-scrollable" autocomplete="off">{{#each view.parentView.content.configs}}',
          '{{#if isVisible}}',
          '<div class="row-fluid control-group">',
          '   <div {{bindAttr class="errorMessage:error :control-label-span :span4"}}>',
          '     <label>{{displayName}}</label>',
          '   </div>',
          '   <div {{bindAttr class="errorMessage:error :control-group :span8"}}>',
          '     {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs" }}',
          '     <span class="help-inline">{{errorMessage}}</span>',
          '   </div>',
          '</div>',
          '{{/if}}',
          '{{/each}}</form>'
        ].join(''))
      }),
      /**
       * Insert extra config in popup according to queue
       *
       * the mapred.queue.default.acl-administer-jobs turns into two implicit configs:
       * "Admin Users" field and "Admin Groups" field
       * the mapred.queue.default.acl-submit-job turns into two implicit configs:
       * "Users" field and "Groups" field
       * Add implicit config that contain "Queue Name"
       * @param content
       * @return {*}
       */
      insertExtraConfigs: function (content) {
        var that = this;
        var admin = content.configs.findProperty('name', self.getUserAndGroupNames(content.name)[1]).get('value');
        var submit = content.configs.findProperty('name', self.getUserAndGroupNames(content.name)[0]).get('value');
        admin = (admin) ? admin.split(' ') : [''];
        submit = (submit) ? submit.split(' ') : [''];
        if (admin.length < 2) {
          admin.push('');
        }
        if (submit.length < 2) {
          submit.push('');
        }
        var nameField = App.ServiceConfigProperty.create({
          name: 'queueName',
          displayName: Em.I18n.t('services.mapReduce.extraConfig.queue.name'),
          description: Em.I18n.t('services.mapReduce.description.queue.name'),
          value: (content.name == '<queue-name>') ? '' : content.name,
          validate: function () {
            var queueNames = self.get('queues').mapProperty('name');
            var value = this.get('value');
            var isError = false;
            var regExp = /^[a-z]([\_\-a-z0-9]{0,50})\$?$/i;
            if (value == '') {
              if (this.get('isRequired')) {
                this.set('errorMessage', 'This is required');
                isError = true;
              } else {
                return;
              }
            }
            if (!isError) {
              if ((queueNames.indexOf(value) !== -1) && (value != content.name)) {
                this.set('errorMessage', 'Queue name is already used');
                isError = true;
              }
            }
            if (!isError) {
              if (!regExp.test(value)) {
                this.set('errorMessage', 'Incorrect input');
                isError = true;
              }
            }
            if (!isError) {
              this.set('errorMessage', '');
            }
          }.observes('value'),
          isRequired: true,
          isVisible: true,
          isEditable: self.get('canEdit'),
          index: 0
        });
        nameField.validate();
        content.configs.unshift(nameField);

        var submitUser = App.ServiceConfigProperty.create({
          name: self.getUserAndGroupNames(content.name)[0],
          displayName: Em.I18n.t('common.users'),
          value: submit[0],
          description: Em.I18n.t('services.mapReduce.description.queue.submit.user'),
          isRequired: true,
          isVisible: true,
          type: 'USERS',
          displayType: "UNIXList",
          isEditable: self.get('canEdit'),
          index: 3
        });

        var submitGroup = App.ServiceConfigProperty.create({
          name: self.getUserAndGroupNames(content.name)[0],
          displayName: Em.I18n.t('services.mapReduce.config.queue.groups'),
          description: Em.I18n.t('services.mapReduce.description.queue.submit.group'),
          value: submit[1],
          isRequired: true,
          isVisible: true,
          "displayType": "UNIXList",
          type: 'GROUPS',
          isEditable: self.get('canEdit'),
          index: 4
        });

        var adminUser = App.ServiceConfigProperty.create({
          name: self.getUserAndGroupNames(content.name)[1],
          displayName: Em.I18n.t('services.mapReduce.config.queue.adminUsers'),
          description: Em.I18n.t('services.mapReduce.description.queue.admin.user'),
          value: admin[0],
          isRequired: true,
          isVisible: true,
          type: 'USERS',
          displayType: "UNIXList",
          isEditable: self.get('canEdit'),
          index: 5
        });

        var adminGroup = App.ServiceConfigProperty.create({
          name: self.getUserAndGroupNames(content.name)[1],
          displayName: Em.I18n.t('services.mapReduce.config.queue.adminGroups'),
          value: admin[1],
          description: Em.I18n.t('services.mapReduce.description.queue.admin.group'),
          isRequired: true,
          isVisible: true,
          "displayType": "UNIXList",
          type: 'GROUPS',
          isEditable: self.get('canEdit'),
          index: 6
        });

        submitUser.reopen({
          validate: function () {
            that.userGroupValidation(this, submitGroup);
          }.observes('value')
        });
        submitGroup.reopen({
          validate: function () {
            that.userGroupValidation(this, submitUser);
          }.observes('value')
        });
        adminUser.reopen({
          validate: function () {
            that.userGroupValidation(this, adminGroup);
          }.observes('value')
        });
        adminGroup.reopen({
          validate: function () {
            that.userGroupValidation(this, adminUser);
          }.observes('value')
        });

        submitUser.validate();
        adminUser.validate();
        content.configs.push(submitUser);
        content.configs.push(submitGroup);
        content.configs.push(adminUser);
        content.configs.push(adminGroup);

        return content;
      },
      /**
       * Validate by follow rules:
       * Users can be blank. If it is blank, Groups must not be blank.
       * Groups can be blank. If it is blank, Users must not be blank.
       * @param context
       * @param boundConfig
       */
      userGroupValidation: function (context, boundConfig) {
        if (context.get('value') == '') {
          if (boundConfig.get('value') == '') {
            context._super();
          } else {
            boundConfig.validate();
          }
        } else {
          if (boundConfig.get('value') == '') {
            boundConfig.set('errorMessage', '');
          }
          context._super();
        }
      }
    })
  }
});
