/**
 * 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');
/**
 * Used to manage slave component config. User could create different settings for separate group
 * @type {*}
 */
App.SlaveComponentGroupsController = Em.ArrayController.extend({

  name: 'slaveComponentGroupsController',

  contentBinding: 'App.router.wizardStep7Controller.slaveComponentHosts',

  stepConfigsBinding: 'App.router.wizardStep7Controller.stepConfigs',

  serviceBinding: 'App.router.wizardStep7Controller.selectedService',

  servicesBinding: 'App.router.wizardStep7Controller.content.services',

  clearStep: function () {

  },

  loadStep: function () {
    this.clearStep();
    this.loadGroups();
  },

  loadGroups: function () {

    this.get('stepConfigs').forEach(function (_serviceConfig) {
      var categoryConfig = _serviceConfig.get('configCategories');
      if (categoryConfig.someProperty('isForSlaveComponent', true)) {
        var slaveCategory = categoryConfig.findProperty('isForSlaveComponent', true);
        // this.get('content') -> Output of Step 6: Mapping of each slave component and set of hosts it runs on
        if (this.get('content')) {
          if (this.get('content').someProperty('componentName', slaveCategory.get('primaryName'))) {
            // component --> each column in Step 6 is a component ( slave component )
            var component = this.get('content').findProperty('componentName', slaveCategory.get('primaryName'));
            // slaveConfigs --> originally set as null in the class App.SlaveCategory in model/service_config.js
            var slaveConfigs = slaveCategory.get('slaveConfigs');
            
            slaveCategory.set('slaveConfigs', App.SlaveConfigs.create(component));
            var slaveGroups = [];
            if (component.groups) {
              component.groups.forEach(function (_group) {
                slaveGroups.pushObject(_group);
              }, this);
              slaveCategory.set('slaveConfigs.groups', slaveGroups);
            }
            slaveCategory.set('slaveConfigs.componentName', component.componentName);
            slaveCategory.set('slaveConfigs.displayName', component.displayName);
            /*slaveCategory.set('slaveConfigs.groups.name', component.get('name'));
             slaveCategory.set('slaveConfigs.groups.index', component.get('index'));
             slaveCategory.set('slaveConfigs.groups.type', component.get('type'));
             slaveCategory.set('slaveConfigs.groups.active', component.get('active'));*/
            if (!slaveCategory.get('slaveConfigs.groups')) {
              slaveCategory.set('slaveConfigs.groups', []);
              var componentProperties = this.componentProperties(_serviceConfig.serviceName);
              var defaultGroup = {name: 'Default', index: 'default', type: 'default', active: true, properties: componentProperties};
              slaveCategory.get('slaveConfigs.groups').pushObject(App.Group.create(defaultGroup));
            }
          }
        }
      }
    }, this);
  },

  // returns key-value pairs i.e. all fields for slave component for this specific service.
  componentProperties: function (serviceName) {

    var serviceConfigs = require('data/service_configs').findProperty('serviceName', serviceName);

    var configs = [];
    var componentName = null;
    switch (serviceName) {
      case 'HDFS':
        componentName = 'DataNode';
        break;
      case 'MAPREDUCE':
        componentName = 'TaskTracker';
        break;
      case 'HBASE':
        componentName = 'RegionServer';
    }
    var slaveConfigs = serviceConfigs.configs.filterProperty('category', componentName);
    slaveConfigs.forEach(function (_serviceConfigProperty) {
      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);

      switch(serviceConfigProperty.name){
        case 'dfs_data_dir' :
          serviceConfigProperty.initialValue();
          break;
        case 'mapred_local_dir' :
          serviceConfigProperty.initialValue();
          break;
      }
      configs.pushObject(serviceConfigProperty);
      serviceConfigProperty.validate();
    }, this);
    return configs;
  },

  selectedComponentName: function () {
    switch (App.router.get('wizardStep7Controller.selectedService.serviceName')) {
      case 'HDFS':
        return { name: 'DATANODE',
          displayName: 'DataNode'};
      case 'MAPREDUCE':
        return { name: 'TASKTRACKER',
          displayName: 'TaskTracker'};

      case 'HBASE':
        return { name: 'HBASE_REGIONSERVER',
          displayName: 'RegionServer'};
      default:
        return null;
    }

  }.property('App.router.wizardStep7Controller.selectedService'),

  selectedComponentDisplayName: function() {
    return App.format.role(this.get('selectedComponentName'));
  }.property('selectedComponentName'),

  selectedSlaveComponent: function () {
    var selectedComponentName = this.get('selectedComponentName') ? this.get('selectedComponentName').displayName : null;
    var configs = null;
    if (selectedComponentName) {
      App.router.get('wizardStep7Controller.stepConfigs').forEach(function (_serviceConfig) {
        var categoryConfig = _serviceConfig.get('configCategories');
        if (categoryConfig.someProperty('name', selectedComponentName)) {
          configs = categoryConfig.findProperty('name', selectedComponentName).get('slaveConfigs');
        }
      }, this);
    }
    return configs;
  }.property('selectedComponentName', 'stepConfigs.@each.configCategories', 'stepConfigs.@each.configCategories.@each.slaveConfigs'),

  hosts: function () {
    if (this.get('selectedSlaveComponent')) {
      return this.get('selectedSlaveComponent').get('hosts');
    }
  }.property('selectedSlaveComponent'),

  groups: function () {
    var hosts = this.get('hosts');
    if(hosts){
      return hosts.mapProperty('group').uniq();
    }
  }.property('hosts'),

  componentGroups: function () {
    var component = this.get('selectedSlaveComponent');
    if (component && component.get('groups')) {
      return component.get('groups');
    }
    return [];
  }.property('selectedSlaveComponent', 'selectedSlaveComponent.groups', 'stepConfigs.@each.configCategories.@each.slaveConfigs.groups.@each.properties.@each.value'),


  getGroupsForDropDown: function () {
    return this.get('componentGroups').getEach('name');
  }.property('selectedComponentName', 'componentGroups.@each.name'),

  activeGroup: function () {
    var componentGroups = this.get('componentGroups');
    if (componentGroups) {
      var active = componentGroups.findProperty('active', true);
      if (active){
        return active;
      }
    }
    return null;
  }.property('componentGroups.@each.active', 'componentGroups.@each.name', 'componentGroups.@each.properties.@each.value'),


  /**
   * Show slave hosts to groups popup
   * @param event
   */
  showAddSlaveComponentGroup: function (event) {
    var componentName = event.context;
    var component = this.get('selectedSlaveComponent');
    App.ModalPopup.show({
      header: componentName + ' Groups',
      bodyClass: Ember.View.extend({
        controllerBinding: 'App.router.slaveComponentGroupsController',
        templateName: require('templates/wizard/slave_component_hosts_popup')
      }),
      onPrimary: function (event) {
        if (component.tempSelectedGroups && component.tempSelectedGroups.length) {
          component.tempSelectedGroups.forEach(function (item) {
            var changed = component.get('hosts').filterProperty('hostName', item.hostName);
            changed.setEach('group', item.groupName);
          })
        }
        delete component.tempSelectedGroups;
        this.hide();
      },
      onSecondary: function (event) {
        delete component.tempSelectedGroups;
        this.hide();
      },
      onClose: function (event) {
        delete component.tempSelectedGroups;
        this.hide();
      }
    });
  },

  /**
   * Utility method. Save temporary info about changes in <code>slave hosts to groups</code> popup
   * @param host
   * @param groupName
   */
  changeHostGroup: function (host, groupName) {
    var component = this.get('selectedSlaveComponent');
    if (component.tempSelectedGroups === undefined) {
      component.tempSelectedGroups = [];
    }
    var values = component.tempSelectedGroups.filterProperty('hostName', host.hostName);
    if (values.length === 0)
      component.tempSelectedGroups.pushObject({hostName: host.hostName, groupName: groupName});
    else
      values.setEach('groupName', groupName);

  },

  /**
   * add new group to component(click on button)
   */
  addSlaveComponentGroup: function () {
    var component = this.get('selectedSlaveComponent');
    var newGroupName = 'New Group';
    component.get('groups').setEach('active', false);
    var newGroups = component.get('groups').filterProperty('name', newGroupName);
    if (newGroups.length === 0){
      component.newGroupIndex = 0;
    }
    else {
      component.newGroupIndex = component.newGroupIndex || 0;
      this.checkGroupName();
      newGroupName = 'New Group ' + component.newGroupIndex;
    }
    var newGroup = {name: newGroupName, index: component.newGroupIndex, type: 'new', active: true, properties: this.componentProperties(App.router.get('wizardStep7Controller.selectedService.serviceName'))};
    component.groups.pushObject(App.Group.create(newGroup));
    $('.remove-group-error').hide();
  },

  checkGroupName: function () {
    var component = this.get('selectedSlaveComponent');
    component.newGroupIndex++;
    var newGroupName = 'New Group ' + component.newGroupIndex;
    var groups = component.get('groups').filterProperty('name', newGroupName);
    if (groups.length !== 0) {
      this.checkGroupName();
    }
  },

  /**
   * Onclick handler for <code>choose hosts for slave group</code> link
   * @param event
   */
  showEditSlaveComponentGroups: function (event) {
    this.showAddSlaveComponentGroup(event);
  },

  getHostsByGroup: function (group) {
    var hosts = this.get('hosts');
    if(hosts){
      return hosts.filterProperty('group', group.name);
    }
  },

  /**
   * Change tab
   * @param event
   */
  showSlaveComponentGroup: function (event) {
    var component = this.get('selectedSlaveComponent');
    if(!component.groups){

    }
    component.get('groups').setEach('active', false);
    var group = component.get('groups').filterProperty('name', event.context.name);
    group.setEach('active', true);
    var assignedHosts = component.get('hosts').filterProperty('group', event.context.name);
    if (assignedHosts.length === 0) {
      $('.remove-group-error').hide();
    }
  },

  /**
   * Remove tab
   * @param event
   */
  removeSlaveComponentGroup: function (event) {
    var group = event.context;
    var component = this.get('selectedSlaveComponent');
    var assignedHosts = component.get('hosts').filterProperty('group', group.name);
    if (assignedHosts.length !== 0) {
      $('.remove-group-error').show();
    } else {
      $('.remove-group-error').hide();
      var key = component.groups.indexOf(group);
      component.groups.removeObject(component.groups[key]);

      var newGroups = component.groups.filterProperty('type', 'new');
      if (newGroups.length == 0)
        component.newGroupIndex = 0;
      else {
        var lastNewGroup = newGroups[newGroups.length - 1];
        component.newGroupIndex = lastNewGroup.index;
      }
      if (group.active) {
        var lastGroup;
        if (key === component.groups.length)
          lastGroup = component.groups.slice(key - 1, key);
        else lastGroup = component.groups.slice(key, key + 1);
        lastGroup.setEach('active', true);
      }
    }
  },

  /**
   * change group name of slave component
   * @param group
   * @param newGroupName
   * @return {Boolean}
   */
  changeSlaveGroupName: function (group, newGroupName) {
    var component = this.get('selectedSlaveComponent');
    var isExist = component.get('groups').filterProperty('name', newGroupName);
    if (isExist.length !== 0)
      return true;
    else {
      var assignedHosts = component.get('hosts').filterProperty('group', group.name);
      if (assignedHosts.length !== 0){
        assignedHosts.setEach('group', newGroupName);
      }
      var groupFilter = component.get('groups').filterProperty('name', group.name);
      groupFilter.setEach('name', newGroupName);
    }
    return false;
  }

});
