/**
 * 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');

/**
 * Default success callback for ajax-requests in this module
 * @type {Function}
 */
var defaultSuccessCallback = function(data, ajaxOptions, params) {
  App.router.get('userSettingsController').dataLoading('show_bg').done(function(initValue) {
    params.query && params.query.set('status', 'SUCCESS');
    if (initValue) {
      App.router.get('backgroundOperationsController').showPopup();
    }
  });
};
/**
 * Default error callback for ajax-requests in this module
 * @param {Object} xhr
 * @param {String} textStatus
 * @param {String} error
 * @param {Object} opt
 * @param {Object} params
 * @type {Function}
 */
var defaultErrorCallback = function(xhr, textStatus, error, opt, params) {
  params.query && params.query.set('status', 'FAIL');
  App.ajax.defaultErrorHandler(xhr, opt.url, 'POST', xhr.status);
};

/**
 * Contains helpful utilities for handling batch and scheduled requests.
 */
module.exports = {

  /**
   * Some services have components which have a need for rolling restarts. This
   * method returns the name of the host-component which supports rolling
   * restarts for a service.
   * @param {String} serviceName
   */
  getRollingRestartComponentName: function(serviceName) {
    var rollingRestartComponents = {
      HDFS: 'DATANODE',
      YARN: 'NODEMANAGER',
      HBASE: 'HBASE_REGIONSERVER',
      STORM: 'SUPERVISOR'
    };
    return rollingRestartComponents[serviceName] ? rollingRestartComponents[serviceName] : null;
  },

  /**
   * Facade-function for restarting host components of specific service
   * @param {String} serviceDisplayName for which service hostComponents should be restarted
   * @param {String} serviceName for which service hostComponents should be restarted
   * @param {bool} staleConfigsOnly restart only hostComponents with <code>staleConfig</code> true
   * @param {Object} query
   * @param {bool} runMmOperation
   */
  restartAllServiceHostComponents: function(serviceDisplayName, serviceName, staleConfigsOnly, query, runMmOperation) {
    const context = staleConfigsOnly ?
      Em.I18n.t('rollingrestart.context.allWithStaleConfigsForSelectedService').format(serviceDisplayName) :
      Em.I18n.t('rollingrestart.context.allForSelectedService').format(serviceDisplayName);

    if (runMmOperation) {
      this.turnOnOffPassiveRequest('ON', Em.I18n.t('passiveState.turnOnFor').format(serviceName), serviceName);
    }
    this.getComponentsFromServer({
      services: [serviceName],
      staleConfigs: staleConfigsOnly ? staleConfigsOnly : null,
      passiveState: 'OFF',
      displayParams: ['host_components/HostRoles/component_name']
    }, data => {
      const hostComponents = this.getRestartComponentsArray(data);
      this.restartHostComponents(hostComponents, context, 'SERVICE', query);
    });
  },

  restartCertainServiceHostComponents: function (serviceName, components, hosts, label, query, runMmOperation) {
    const context = Em.I18n.t('rollingrestart.context.allForSelectedService').format(label);
    if (runMmOperation) {
      this.turnOnOffPassiveRequest('ON', Em.I18n.t('passiveState.turnOnFor').format(serviceName), serviceName);
    }
    this.getComponentsFromServer({
      services: serviceName && [serviceName],
      hosts,
      components,
      passiveState: 'OFF',
      displayParams: ['host_components/HostRoles/component_name']
    }, data => {
      const hostComponents = this.getRestartComponentsArray(data);
      this.restartHostComponents(hostComponents, context, 'SERVICE', query);
    });
  },

  getRestartComponentsArray: function (data) {
    let hostComponents = [];
    data.items.forEach(host => {
      host.host_components.forEach(hostComponent => {
        hostComponents.push(Em.Object.create({
          componentName: hostComponent.HostRoles.component_name,
          hostName: host.Hosts.host_name
        }));
      });
    });
    return hostComponents;
  },

  /**
   * construct URL from parameters for request in <code>getComponentsFromServer()</code>
   * @param {object} options
   * @return {{fields: string, params: string}}
   */
  constructComponentsCallUrl: function (options) {
    var multipleValueParams = {
        'services': 'host_components/HostRoles/service_name.in(<entity-names>)',
        'hosts': 'Hosts/host_name.in(<entity-names>)',
        'components': 'host_components/HostRoles/component_name.in(<entity-names>)'
      },
      singleValueParams = {
        staleConfigs: 'host_components/HostRoles/stale_configs=',
        passiveState: 'Hosts/maintenance_state=',
        workStatus: 'host_components/HostRoles/state='
      },
      displayParams = options.displayParams || [],
      urlParams = '',
      addAmpersand = false;

    for (var i in multipleValueParams) {
      var arrayParams = options[i];
      if (Array.isArray(arrayParams) && arrayParams.length > 0) {
        if (addAmpersand) {
          urlParams += '&';
          addAmpersand = false;
        }
        urlParams += multipleValueParams[i].replace('<entity-names>', arrayParams.join(','));
        addAmpersand = true;
      }
    }

    for (var j in singleValueParams) {
      var param = options[j];
      if (!Em.isNone(param)) {
        urlParams += (addAmpersand) ? '&' : '';
        urlParams += singleValueParams[j] + param.toString();
        addAmpersand = true;
      }
    }
    var params = urlParams,
      fields = '';
    displayParams.forEach(function (displayParam, index, array) {
      if (index === 0) {
        fields += (addAmpersand) ? '&' : '';
        fields += 'fields=';
      }
      fields += displayParam;
      fields += (array.length === (index + 1)) ? '' : ",";
    });
    fields += '&minimal_response=true';

    return {fields: fields.substring(1, fields.length), params: params};
  },

  /**
   * make GET call to server in order to obtain host-components
   * which correspond to filter params from <code>options</code>
   * @param options
   * @param callback
   */
  getComponentsFromServer: function (options, callback) {
    var request_parameters = this.constructComponentsCallUrl(options);
    return App.ajax.send({
      name: 'host.host_components.filtered',
      sender: this,
      data: {
        parameters: request_parameters.params,
        fields: request_parameters.fields,
        callback: callback
      },
      success: 'getComponentsFromServerSuccessCallback'
    });
  },

  /**
   * pass request outcome to <code>callback()<code>
   * @param data
   * @param opt
   * @param params
   */
  getComponentsFromServerSuccessCallback: function (data, opt, params) {
    params.callback(data);
  },

  /**
   * Restart list of host components
   * @param {Ember.Enumerable} hostComponentsList list of host components should be restarted
   * @param {String} context message to show in BG popup
   * @param {String} level - operation level, can be ("CLUSTER", "SERVICE", "HOST", "HOSTCOMPONENT")
   * @param {String} query
   */
  restartHostComponents: function (hostComponentsList, context, level, query) {
    context = context || Em.I18n.t('rollingrestart.context.default');
    /**
     * Format: {
     *  'DATANODE': ['host1', 'host2'],
     *  'NAMENODE': ['host1', 'host3']
     *  ...
     * }
     */
    var componentToHostsMap = {};
    var hosts = [];
    hostComponentsList.forEach(function(hc) {
      var hostName = hc.get('hostName');
      var componentName = hc.get('componentName');
      if (!componentToHostsMap[componentName]) {
        componentToHostsMap[componentName] = [];
      }
      componentToHostsMap[componentName].push(hostName);
      hosts.push(hostName);
    });
    var resource_filters = [];
    for (var componentName in componentToHostsMap) {
      if (componentToHostsMap.hasOwnProperty(componentName)) {
        resource_filters.push({
          service_name: App.StackServiceComponent.find(componentName).get('serviceName'),
          component_name: componentName,
          hosts: componentToHostsMap[componentName].join(",")
        });
      }
    }
    if (hostComponentsList.length > 0) {
      var serviceComponentName = hostComponentsList[0].get("componentName");
      var serviceName = App.StackServiceComponent.find(serviceComponentName).get('serviceName');
      var operation_level = this.getOperationLevelObject(level, serviceName,
        serviceComponentName);
    }


    if (resource_filters.length) {
      App.ajax.send({
        name: 'restart.hostComponents',
        sender: {
          successCallback: defaultSuccessCallback,
          errorCallback: defaultErrorCallback
        },
        data: {
          context: context,
          resource_filters: resource_filters,
          query: query,
          operation_level: operation_level
        },
        success: 'successCallback',
        error: 'errorCallback',
        showLoadingPopup: true
      });
    }
  },

  /**
   * @param {String} level - operation level name, can be ("CLUSTER", "SERVICE", "HOST", "HOSTCOMPONENT")
   * @param {String} serviceName
   * @param {String} componentName
   * @returns {Object} {{level: *, cluster_name: *}} - operation level object
   * @method getOperationLevelObject - create operation level object to be included into ajax query
   */
  getOperationLevelObject: function(level, serviceName, componentName) {
    var operationLevel = {
      "level": level,
      "cluster_name": App.get("clusterName")
    };
    if (level === "SERVICE") {
      operationLevel["service_name"] = serviceName;
    }
    else {
      if (level !== "HOST") {
        operationLevel["service_name"] = serviceName;
        operationLevel["hostcomponent_name"] = componentName;
      }
    }
    return operationLevel;
  },

  turnOnOffPassiveRequest: function(state, message, serviceName, callback) {
    return App.ajax.send({
      'name': 'common.service.passive',
      'sender': {
        'successCallback': callback || defaultSuccessCallback,
        'errorCallback': defaultErrorCallback
      },
      'data': {
        'requestInfo': message,
        'serviceName': serviceName,
        'passive_state': state
      },
      'success': 'successCallback'
    });
  },

  /**
   * Makes a REST call to the server requesting the rolling restart of the
   * provided host components.
   * @param {Array} restartHostComponents list of host components should be restarted
   * @param {Number} batchSize size of each batch
   * @param {Number} intervalTimeSeconds delay between two batches
   * @param {Number} tolerateSize task failure tolerance
   * @param {callback} [successCallback]
   * @param {callback} [errorCallback]
   */
  _doPostBatchRollingRestartRequest: function(restartHostComponents, batchSize, intervalTimeSeconds, tolerateSize, successCallback, errorCallback) {
    successCallback = successCallback || defaultSuccessCallback;
    errorCallback = errorCallback || defaultErrorCallback;

    if (!restartHostComponents.length) {
      return;
    }
    return App.ajax.send({
      name: 'common.batch.request_schedules',
      sender: {
        successCallback: successCallback,
        errorCallback: errorCallback
      },
      data: {
        intervalTimeSeconds: intervalTimeSeconds,
        tolerateSize: tolerateSize,
        batches: this.getBatchesForRollingRestartRequest(restartHostComponents, batchSize)
      },
      success: 'successCallback',
      error: 'errorCallback',
      showLoadingPopup: true
    });
  },

  /**
   * Create list of batches for rolling restart request
   * @param {Array} restartHostComponents list host components should be restarted
   * @param {Number} batchSize size of each batch
   * @returns {Array} list of batches
   */
  getBatchesForRollingRestartRequest: function(restartHostComponents, batchSize) {
    var hostIndex = 0,
        batches = [],
        batchCount = Math.ceil(restartHostComponents.length / batchSize),
        sampleHostComponent = restartHostComponents.objectAt(0),
        componentName = sampleHostComponent.get('componentName'),
        serviceName = sampleHostComponent.get('serviceName');

    for ( var count = 0; count < batchCount; count++) {
      var hostNames = [];
      for ( var hc = 0; hc < batchSize && hostIndex < restartHostComponents.length; hc++) {
        hostNames.push(restartHostComponents.objectAt(hostIndex++).get('hostName'));
      }
      if (hostNames.length) {
        batches.push({
          "order_id" : count + 1,
          "type" : "POST",
          "uri" : "/clusters/" + App.get('clusterName') + "/requests",
          "RequestBodyInfo" : {
            "RequestInfo" : {
              "context" : "_PARSE_.ROLLING-RESTART." + componentName + "." + (count + 1) + "." + batchCount,
              "command" : "RESTART"
            },
            "Requests/resource_filters": [{
              "service_name" : serviceName,
              "component_name" : componentName,
              "hosts" : hostNames.join(",")
            }]
          }
        });
      }
    }
    return batches;
  },

  /**
   * Launches dialog to handle rolling restarts of host components.
   *
   * Rolling restart is supported only for components listed in <code>getRollingRestartComponentName</code>
   * @see getRollingRestartComponentName
   * @param {String} hostComponentName
   *           Type of host-component to restart across cluster
   *          (ex: DATANODE)
   * @param {bool} staleConfigsOnly
   *           Pre-select host-components which have stale
   *          configurations
   */
  launchHostComponentRollingRestart: function(hostComponentName, serviceName, isMaintenanceModeOn, staleConfigsOnly, skipMaintenance) {
    if (App.get('components.rollinRestartAllowed').contains(hostComponentName)) {
      return this.showRollingRestartPopup(hostComponentName, serviceName, isMaintenanceModeOn, staleConfigsOnly, null, skipMaintenance);
    }
    return this.showWarningRollingRestartPopup(hostComponentName);
  },

  /**
   * Show popup with rolling restart dialog
   * @param {String} hostComponentName name of the host components that should be restarted
   * @param {String} serviceName
   * @param {boolean} isMaintenanceModeOn
   * @param {bool} staleConfigsOnly restart only components with <code>staleConfigs</code> = true
   * @param {App.hostComponent[]} [hostComponents] list of hostComponents that should be restarted
   * @param {boolean} [skipMaintenance]
   * Using this parameter will reset hostComponentName
   */
  showRollingRestartPopup: function(hostComponentName, serviceName, isMaintenanceModeOn, staleConfigsOnly, hostComponents, skipMaintenance) {
    hostComponents = hostComponents || [];
    var componentDisplayName = App.format.role(hostComponentName, false);
    var self = this;
    if (!componentDisplayName) {
      componentDisplayName = hostComponentName;
    }
    var title = Em.I18n.t('rollingrestart.dialog.title').format(componentDisplayName);
    var viewExtend = {
      turnOnMmMsg: Em.I18n.t('passiveState.turnOnFor').format(serviceName),
      turnOnMm: false,
      staleConfigsOnly : staleConfigsOnly,
      hostComponentName : hostComponentName,
      skipMaintenance: skipMaintenance,
      serviceName: serviceName,
      isServiceInMM: isMaintenanceModeOn,
      didInsertElement: function () {
        var view = this;

        this.set('parentView.innerView', this);
        if (hostComponents.length) {
          view.initialize();
          return;
        }

        self.getComponentsFromServer({
          components: [hostComponentName],
          displayParams: ['host_components/HostRoles/stale_configs', 'Hosts/maintenance_state', 'host_components/HostRoles/maintenance_state'],
          staleConfigs: staleConfigsOnly ? staleConfigsOnly : null
        }, function (data) {
          var wrappedHostComponents = [];
          data.items.forEach(function (host) {
            host.host_components.forEach(function(hostComponent) {
              wrappedHostComponents.push(Em.Object.create({
                componentName: hostComponent.HostRoles.component_name,
                serviceName: App.StackServiceComponent.find(hostComponent.HostRoles.component_name).get('serviceName'),
                hostName: host.Hosts.host_name,
                staleConfigs: hostComponent.HostRoles.stale_configs,
                hostPassiveState: host.Hosts.maintenance_state,
                passiveState: hostComponent.HostRoles.maintenance_state
              }));
            });
          });
          view.set('allHostComponents', wrappedHostComponents);
          view.initialize();
        });
      }
    };
    if (hostComponents.length) {
      viewExtend.allHostComponents = hostComponents;
    }

    App.ModalPopup.show({
      header : title,
      hostComponentName : hostComponentName,
      serviceName: serviceName,
      isServiceInMM: isMaintenanceModeOn,
      staleConfigsOnly : staleConfigsOnly,
      skipMaintenance: skipMaintenance,
      innerView : null,
      bodyClass : App.RollingRestartView.extend(viewExtend),
      classNames : [ 'rolling-restart-popup' ],
      primary : Em.I18n.t('rollingrestart.dialog.primary'),
      onPrimary : function() {
        var dialog = this;
        var restartComponents = this.get('innerView.restartHostComponents');
        var batchSize = this.get('innerView.batchSize');
        var waitTime = this.get('innerView.interBatchWaitTimeSeconds');
        var tolerateSize = this.get('innerView.tolerateSize');
        if (this.get('innerView.turnOnMm')) {
          self.turnOnOffPassiveRequest('ON', Em.I18n.t('passiveState.turnOnFor').format(serviceName), serviceName.toUpperCase());
        }
        self._doPostBatchRollingRestartRequest(restartComponents, batchSize, waitTime, tolerateSize, function(data, ajaxOptions, params) {
          dialog.hide();
          defaultSuccessCallback(data, ajaxOptions, params);
        });
      },
      updateButtons : function() {
        var errors = this.get('innerView.errors');
        this.set('disablePrimary', (errors != null && errors.length > 0))
      }.observes('innerView.errors')
    });
  },

  /**
   * Show warning popup about not supported host components
   * @param {String} hostComponentName
   */
  showWarningRollingRestartPopup: function(hostComponentName) {
    var componentDisplayName = App.format.role(hostComponentName, false) || hostComponentName;
    var title = Em.I18n.t('rollingrestart.dialog.title').format(componentDisplayName);
    var msg = Em.I18n.t('rollingrestart.notsupported.hostComponent').format(componentDisplayName);

    return App.ModalPopup.show({
      header : title,
      secondary : false,
      msg : msg,
      bodyClass : Em.View.extend({
        template : Em.Handlebars.compile('<div class="alert alert-warning">{{msg}}</div>')
      })
    });
  },

  /**
   * Warn user that alerts will be updated in few minutes
   * @param {String} passiveState
   */
  infoPassiveState: function(passiveState) {
    var enabled = passiveState == 'OFF' ? 'enabled' : 'suppressed';
    App.ModalPopup.show({
      header: Em.I18n.t('common.information'),
      secondary: null,
      bodyClass: Em.View.extend({
        template: Em.Handlebars.compile('<p>{{view.message}}</p>'),
        message: Em.I18n.t('hostPopup.warning.alertsTimeOut').format(passiveState.toLowerCase(), enabled)
      })
    });
  },

  /**
   * Retrieves the latest information about a specific request schedule
   * identified by 'requestScheduleId'
   *
   * @param {Number} requestScheduleId ID of the request schedule to get
   * @param {Function} successCallback Called with request_schedule data from server. An
   *          empty object returned for invalid ID.
   * @param {Function} errorCallback Optional error callback. Default behavior is to
   *          popup default error dialog.
   */
  getRequestSchedule: function(requestScheduleId, successCallback, errorCallback) {
    if (requestScheduleId != null && !isNaN(requestScheduleId) && requestScheduleId > -1) {
      errorCallback = errorCallback || defaultErrorCallback;
      App.ajax.send({
        name : 'request_schedule.get',
        sender : {
          successCallbackFunction: successCallback,
          errorCallbackFunction: errorCallback
        },
        data : {
          request_schedule_id : requestScheduleId
        },
        success : 'successCallbackFunction',
        error : 'errorCallbackFunction'
      });
    } else {
      successCallback({});
    }
  },

  /**
   * Attempts to abort a specific request schedule identified by 'requestScheduleId'
   *
   * @param {Number} requestScheduleId ID of the request schedule to get
   * @param {Function} successCallback Called when request schedule successfully aborted
   * @param {Function} errorCallback Optional error callback. Default behavior is to
   *          popup default error dialog.
   */
  doAbortRequestSchedule: function(requestScheduleId, successCallback, errorCallback) {
    if (requestScheduleId != null && !isNaN(requestScheduleId) && requestScheduleId > -1) {
      errorCallback = errorCallback || defaultErrorCallback;
      App.ajax.send({
        name : 'common.delete.request_schedule',
        sender : {
          successCallbackFunction: successCallback,
          errorCallbackFunction: errorCallback
        },
        data : {
          request_schedule_id : requestScheduleId
        },
        success : 'successCallbackFunction',
        error : 'errorCallbackFunction'
      });
    } else {
      successCallback({});
    }
  }
};
