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

/**
 * Mixin for wizard controller for showing command progress on wizard pages
 * This should
 * @type {Ember.Mixin}
 */
App.wizardProgressPageControllerMixin = Em.Mixin.create(App.InstallComponent, {
  controllerName: '',
  clusterDeployState: 'WIZARD_DEPLOY',
  status: 'IN_PROGRESS',
  tasks: [],
  commands: [],
  currentRequestIds: [], //todo: replace with using requestIds from tasks
  logs: [],
  currentTaskId: null,
  POLL_INTERVAL: 4000,
  isSubmitDisabled: true,
  isBackButtonDisabled: true,
  stages: [],
  /**
   * List of statuses that inform about the end of request progress.
   * @type {String[]}
   */
  completedStatuses: ['COMPLETED', 'FAILED', 'TIMEDOUT', 'ABORTED'],
  currentPageRequestId: null,
  isSingleRequestPage: false,
  isCommandLevelRetry: Em.computed.not('isSingleRequestPage'),
  showRetry: false,
  /**
   * Show whether tasks data was loaded
   * @type {Boolean}
   */
  isLoading: false,

  k: Em.K,
  /**
   *  tasksMessagesPrefix should be overloaded by any controller including the mixin
   */
  tasksMessagesPrefix: '',

  loadStep: function () {
    this.clearStep();
    var self = this;
    if (!self.isSingleRequestPage) {
      this.initStep();
    } else {
      var requestIds = this.get('content.tasksRequestIds');
      var currentRequestId = requestIds && requestIds[0][0];
      if (!currentRequestId) {
        this.set('isLoaded', false);
        this.submitRequest();
      } else {
        self.set('currentPageRequestId', currentRequestId);
        self.doPollingForPageRequest();
      }
    }
  },

  initStep: function () {
    this.initializeTasks();
    if (!this.isSingleRequestPage) {
      this.loadTasks();
    }
    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
    if (this.isSingleRequestPage) {
      var dfd = $.Deferred();
      var dfdObject = {
        deferred: dfd,
        isJqueryPromise: true
      };
      this.onTaskStatusChange(dfdObject);
      return dfd.promise();
    } else {
      this.onTaskStatusChange();
    }
  },

  clearStep: function () {
    this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
    this.set('isSubmitDisabled', true);
    this.set('isBackButtonDisabled', true);
    this.set('tasks', []);
    this.set('currentRequestIds', []);
    this.set('isLoaded', false);
  },

  /**
   * Clear stages info for single page request.
   */
  clearStage: function() {
    this.setDBProperties({
      tasksRequestIds: null,
      tasksStatuses: null
    });
    this.set('showRetry', false);
    this.set('content.tasksRequestIds', null);
    this.set('content.tasksStatuses', null);
    this.set('content.currentTaskId', null);
    this.get('stages').clear();
  },

  retry: function () {
    this.set('showRetry', false);
    this.get('tasks').setEach('status','PENDING');
    this.loadStep();
  },

  submitRequest: function () {
    var self = this;
    return App.ajax.send({
      name: this.get('request.ajaxName'),
      data: this.get('request.ajaxData'),
      sender: this,
      error: 'onSingleRequestError',
      success: 'submitRequestSuccess',
      kdcCancelHandler: function() {
        self.set('status', 'FAILED');
        self.set('isLoaded', true);
        self.set('showRetry', true);
      }
    });
  },

  submitRequestSuccess: function(data, result, request) {
    if (data) {
      this.set('currentPageRequestId', data.Requests.id);
      this.doPollingForPageRequest();
    } else {
      //Step has been successfully completed
      if (request.status === 200) {
        this.set('status', 'COMPLETED');
        this.set('isSubmitDisabled', false);
        this.set('isLoaded', true);
      }
    }
  },

  doPollingForPageRequest: function () {
    App.ajax.send({
      name: 'admin.poll.kerberize.cluster.request',
      sender: this,
      data: {
        requestId: this.get('currentPageRequestId')
      },
      success: 'initializeStages'
    });
  },

  initializeStages: function (data) {
    var self = this;
    var stages = [];
    this.set('logs', []);
    data.stages.forEach(function (_stage) {
      stages.pushObject(Em.Object.create(_stage.Stage));
    }, this);
    if (!this.get('stages').length) {
      this.get('stages').pushObjects(stages);
      this.initStep().done(function(){
        self.updatePageWithPolledData(data);
      });
    } else {
      this.updatePageWithPolledData(data);
    }
  },

  updatePageWithPolledData: function(data) {
    // If all tasks completed no need to update each task status.
    // Preferable to skip polling of data for completed tasks after page refresh.
    if (this.get('status') === 'COMPLETED') return;
    var self = this;
    var tasks = [];
    var currentPageRequestId = this.get('currentPageRequestId');
    var currentTaskId = this.get('currentTaskId');
    var currentTask = this.get('tasks').findProperty('id', currentTaskId);
    var currentStage =  data.stages.findProperty('Stage.stage_id', currentTask.get('stageId'));
    var tasksInCurrentStage =  currentStage.tasks;
    this.set('logs',tasksInCurrentStage);

    this.setRequestIds(this.get('currentTaskId'), [this.get('currentPageRequestId')]);

    if (!tasksInCurrentStage.someProperty('Tasks.status', 'PENDING') && !tasksInCurrentStage.someProperty('Tasks.status', 'QUEUED') && !tasksInCurrentStage.someProperty('Tasks.status', 'IN_PROGRESS')) {
      this.set('currentRequestIds', []);
      if (tasksInCurrentStage.someProperty('Tasks.status', 'FAILED') || tasksInCurrentStage.someProperty('Tasks.status', 'TIMEDOUT') || tasksInCurrentStage.someProperty('Tasks.status', 'ABORTED')) {
        this.setTaskStatus(currentTaskId, 'FAILED');
      } else {
        this.setTaskStatus(currentTaskId, 'COMPLETED');
      }
    } else {
      var completedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'COMPLETED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'FAILED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'ABORTED').length
        + tasksInCurrentStage.filterProperty('Tasks.status', 'TIMEDOUT').length;
      var queuedActions = tasksInCurrentStage.filterProperty('Tasks.status', 'QUEUED').length;
      var inProgressActions = tasksInCurrentStage.filterProperty('Tasks.status', 'IN_PROGRESS').length;
      var progress = Math.floor(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / tasksInCurrentStage.length * 100);
      this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
    }

    // start polling if current request not completed
    if (!(this.get('completedStatuses').contains(this.get('status')))) {
      window.setTimeout(function () {
        self.doPollingForPageRequest();
      }, self.POLL_INTERVAL);
    }
  },

  initializeTasks: function () {
    var self = this;
    var commands = this.isSingleRequestPage ? this.get('stages') : this.get('commands');
    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
    // check that all stages have been completed for single request type
    var allStagesCompleted = commands.everyProperty('status', 'COMPLETED');
    for (var i = 0; i < commands.length; i++) {
      this.get('tasks').pushObject(Ember.Object.create({
        title: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
        // set COMPLETED status for task if all stages completed successfully
        status: allStagesCompleted ? 'COMPLETED' : 'PENDING',
        id: i,
        stageId: self.isSingleRequestPage ? commands[i].get('stage_id') : null,
        command: self.isSingleRequestPage ? 'k' : commands[i],
        showRetry: false,
        showRollback: false,
        name: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
        displayName: self.isSingleRequestPage ? commands[i].get('context') : Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
        progress: 0,
        isRunning: false,
        requestIds: self.isSingleRequestPage ? [this.get('stages')[0].request_id] : []
      }));
    }
    this.set('isLoaded', true);
  },

  loadTasks: function () {
    var self = this;
    var loadedStatuses = this.get('content.tasksStatuses');
    var loadedRequestIds = this.get('content.tasksRequestIds');
    if (loadedStatuses && loadedStatuses.length === this.get('tasks').length) {
      this.get('tasks').forEach(function (task, i) {
        self.setTaskStatus(task.get('id'), loadedStatuses[i]);
        self.setRequestIds(task.get('id'), loadedRequestIds[i]);
      });
      if (loadedStatuses.contains('IN_PROGRESS')) {
        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('IN_PROGRESS')].get('id');
        this.set('currentRequestIds', this.get('content.requestIds'));
        this.set('currentTaskId', curTaskId);
        this.doPolling();
      } else if (loadedStatuses.contains('QUEUED')) {
        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('QUEUED')].get('id');
        this.set('currentTaskId', curTaskId);
        this.runTask(curTaskId);
      }
    }
  },

  /**
   * remove tasks by command name
   */
  removeTasks: function(commands) {
    var tasks = this.get('tasks');

    commands.forEach(function(command) {
      var cmd = tasks.filterProperty('command', command);
      var index = null;

      if (cmd.length === 0) {
        return false;
      } else {
        index = tasks.indexOf( cmd[0] );
      }

      tasks.splice( index, 1 );
    });
  },

  setTaskStatus: function (taskId, status) {
    this.get('tasks').findProperty('id', taskId).set('status', status);
  },

  setTaskCanSkip: function (taskId, canSkip) {
    this.get('tasks').findProperty('id', taskId).set('canSkip', true);
  },

  setRequestIds: function (taskId, requestIds) {
    this.get('tasks').findProperty('id', taskId).set('requestIds', requestIds);
  },

  retryTask: function () {
    var task = this.get('tasks').findProperty('status', 'FAILED');
    task.set('showRetry', false);
    task.set('showRollback', false);
    this.set('isSubmitDisabled', true);
    this.set('isBackButtonDisabled', true);
    task.set('status', 'PENDING');
  },

  onTaskStatusChange: function (dfdObject) {
    var statuses = this.get('tasks').mapProperty('status');
    var tasksRequestIds = this.get('tasks').mapProperty('requestIds');
    var requestIds = this.get('currentRequestIds');
    // save task info
    App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
    App.router.get(this.get('content.controllerName')).saveTasksRequestIds(tasksRequestIds);
    App.router.get(this.get('content.controllerName')).saveRequestIds(requestIds);
    // call saving of cluster status asynchronous
    // synchronous executing cause problems in Firefox
    var successCallbackData;
    if (dfdObject && dfdObject.isJqueryPromise) {
      successCallbackData =  {deferred: dfdObject.deferred};
    }
    App.clusterStatus.setClusterStatus({
      clusterName: App.router.getClusterName(),
      clusterState: this.get('clusterDeployState'),
      wizardControllerName: this.get('content.controllerName'),
      localdb: App.db.data
    }, {successCallback: this.statusChangeCallback, sender: this, successCallbackData: successCallbackData});
  },

  /**
   * Method that called after saving persist data to server.
   * Switch task according its status.
   */
  statusChangeCallback: function (data) {
    if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
      var nextTask = this.get('tasks').findProperty('status', 'PENDING');
      if (nextTask) {
        this.set('status', 'IN_PROGRESS');
        var taskStatus = this.isSingleRequestPage ? 'IN_PROGRESS' : 'QUEUED';
        this.setTaskStatus(nextTask.get('id'), taskStatus);
        this.set('currentTaskId', nextTask.get('id'));
        this.runTask(nextTask.get('id'));
      } else {
        this.set('status', 'COMPLETED');
        this.set('isSubmitDisabled', false);
        this.set('isBackButtonDisabled', false);
      }
    } else if (this.get('tasks').someProperty('status', 'FAILED')) {
      this.set('status', 'FAILED');
      this.set('isBackButtonDisabled', false);
      if (this.get('isCommandLevelRetry')) {
        this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
      } else {
        this.set('showRetry', true);
      }

      if (this.get('tasks').someProperty('canSkip', true)) {
        this.get('tasks').findProperty('canSkip', true).set('showSkip', true);
      }

      if (App.supports.autoRollbackHA) {
        this.get('tasks').findProperty('status', 'FAILED').set('showRollback', true);
      }
    }
    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRetry', false);
    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRollback', false);
    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showSkip', false);
    this.get('tasks').filterProperty('status', 'IN_PROGRESS').setEach('showSkip', false);

    if (data && data.deferred) {
      data.deferred.resolve();
    }
  },

  /**
   * Run command of appropriate task
   */
  runTask: function (taskId) {
    this[this.get('tasks').findProperty('id', taskId).get('command')]();
  },

  onTaskError: function () {
    this.setTaskStatus(this.get('currentTaskId'), 'FAILED');
  },

  onTaskErrorWithSkip: function () {
    this.onTaskError();
    this.setTaskCanSkip(this.get('currentTaskId'), true);
  },

  onSingleRequestError: function (jqXHR, ajaxOptions, error, opt) {
    App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.type, jqXHR.status);
    this.set('status', 'FAILED');
    this.set('isLoaded', true);
    this.set('showRetry', true);
  },

  onTaskCompleted: function () {
    this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
  },

  /**
   * check whether component installed on specified hosts
   * @param {string} componentName
   * @param {string[]} hostNames
   * @return {$.ajax}
   */
  checkInstalledComponents: function (componentName, hostNames) {
    return App.ajax.send({
      name: 'host_component.installed.on_hosts',
      sender: this,
      data: {
        componentName: componentName,
        hostNames: hostNames.join(',')
      }
    });
  },

  /**
   * make server call to stop services
   * if stopListedServicesFlag == false; stop all services excluding the services passed as parameters
   * if stopListedServicesFlag == true; stop only services passed as parameters
   * if namenode or secondary namenode then stop all services
   * @param services, stopListedServicesFlag, stopAllServices
   * @returns {$.ajax}
   */
  stopServices: function (services, stopListedServicesFlag, stopAllServices) {
    var stopAllServices = stopAllServices || false;
    var stopListedServicesFlag = stopListedServicesFlag || false;
    var data = {
      'ServiceInfo': {
        'state': 'INSTALLED'
      }
    };
    if (stopAllServices) {
      data.context = "Stop all services";
    } else {
      if(!services || !services.length) {
        services = App.Service.find().mapProperty('serviceName').filter(function (service) {
          return service != 'HDFS';
        });
      }
      var servicesList;
      if (stopListedServicesFlag) {
        servicesList = services.join(',');
      } else {
        servicesList =  App.Service.find().mapProperty("serviceName").filter(function (s) {
          return !services.contains(s)
        }).join(',');
      }
      data.context = "Stop required services";
      data.urlParams = "ServiceInfo/service_name.in(" + servicesList + ")";
    }

    return App.ajax.send({
      name: 'common.services.update',
      sender: this,
      data: data,
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  /*tep4
   * make server call to start services
   * if startListedServicesFlag == false; start all services excluding the services passed as parameters
   * if startListedServicesFlag == true; start only services passed as parameters
   * if no parameters are passed; start all services
   * and run smoke tests if runSmokeTest is true
   * @param runSmokeTest
   * @param services
   * @param startListedServicesFlag
   * @returns {$.ajax}
   */
  startServices: function (runSmokeTest, services, startListedServicesFlag) {
    var startListedServicesFlag = startListedServicesFlag || false;
    var skipServiceCheck = App.router.get('clusterController.ambariProperties')['skip.service.checks'] === "true";
    var data = {
      'ServiceInfo': {
        'state': 'STARTED'
      }
    };
    var servicesList;
    if (services && services.length) {
      if (startListedServicesFlag) {
        servicesList = services.join(',');
      } else {
        servicesList =  App.Service.find().mapProperty("serviceName").filter(function (s) {
          return !services.contains(s)
        }).join(',');
      }
      data.context = "Start required services";
      data.urlParams = "ServiceInfo/service_name.in(" + servicesList + ")";
    } else {
      data.context = "Start all services";
    }

    if (runSmokeTest) {
      data.urlParams = data.urlParams ? data.urlParams + '&' : '';
      data.urlParams += 'params/run_smoke_test=' + !skipServiceCheck;
    }

    return App.ajax.send({
      name: 'common.services.update',
      sender: this,
      data: data,
      success: 'startPolling',
      error: 'startServicesErrorCallback'
    });
  },

  startServicesErrorCallback: function (jqXHR, ajaxOptions, error, opt) {
    App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.type, jqXHR.status);
    this.onTaskError(jqXHR, ajaxOptions, error, opt);
  },

  /**
   * Create component on single or multiple hosts.
   *
   * @method createComponent
   * @param {string} componentName - name of the component
   * @param {(string|string[])} hostName - host/hosts where components should be installed
   * @param {string} serviceName - name of the services
   */
  createComponent: function (componentName, hostName, serviceName) {
    var hostNames = (Array.isArray(hostName)) ? hostName : [hostName];
    var self = this;

    this.set('showRetry', false);

    this.checkInstalledComponents(componentName, hostNames).then(function (data) {
      var hostsWithComponents = data.items.mapProperty('HostRoles.host_name');
      var result = hostNames.map(function(item) {
        return {
          componentName: componentName,
          hostName: item,
          hasComponent: hostsWithComponents.contains(item)
        };
      });
      var hostsWithoutComponents = result.filterProperty('hasComponent', false).mapProperty('hostName');
      var taskNum = 1;
      var requestData = {
        "RequestInfo": {
          "query": hostsWithoutComponents.map(function(item) {
            return 'Hosts/host_name=' + item;
          }).join('|')
        },
        "Body": {
          "host_components": [
            {
              "HostRoles": {
                "component_name": componentName
              }
            }
          ]
        }
      };
      if (!!hostsWithoutComponents.length) {
        self.updateAndCreateServiceComponent(componentName).done(function () {
          App.ajax.send({
            name: 'wizard.step8.register_host_to_component',
            sender: self,
            data: {
              data: JSON.stringify(requestData),
              hostName: result.mapProperty('hostName'),
              componentName: componentName,
              serviceName: serviceName,
              taskNum: taskNum,
              cluster: App.get('clusterName')
            },
            success: 'onCreateComponent',
            error: 'onCreateComponent'
          });
        });
      } else {
        self.onCreateComponent(null, null, {
          hostName: result.mapProperty('hostName'),
          componentName: componentName,
          serviceName: serviceName,
          taskNum: taskNum
        }, self);
      }
    });
  },

  onCreateComponent: function () {
    var hostName = arguments[2].hostName;
    var componentName = arguments[2].componentName;
    var taskNum = arguments[2].taskNum;
    var serviceName = arguments[2].serviceName;
    this.updateComponent(componentName, hostName, serviceName, "Install", taskNum);
  },

  onCreateComponentError: function (error) {
    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException') !== -1) {
      this.onCreateComponent();
    } else {
      this.onTaskError();
    }
  },

  /**
   * Update component status on selected hosts.
   *
   * @param {string} componentName
   * @param {(string|string[]|null)} hostName - use null to update components on all hosts
   * @param {string} serviceName
   * @param {string} context
   * @param {number} taskNum
   * @returns {$.ajax}
   */
  updateComponent: function (componentName, hostName, serviceName, context, taskNum) {
    if (hostName && !(hostName instanceof Array)) {
      hostName = [hostName];
    }
    var state = context.toLowerCase() == "start" ? "STARTED" : "INSTALLED";
    return App.ajax.send({
      name: 'common.host_components.update',
      sender: this,
      data: {
        HostRoles: {
          state: state
        },
        query: 'HostRoles/component_name=' + componentName + (hostName ? '&HostRoles/host_name.in(' + hostName.join(',') + ')' : '') + '&HostRoles/maintenance_state=OFF',
        context: context + " " + App.format.role(componentName, false),
        hostName: hostName,
        taskNum: taskNum || 1,
        componentName: componentName,
        serviceName: serviceName
      },
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  /**
   * Update state for array of components of different services and on different hosts
   *
   * @param {Array} components - array of components object with fields serviceName, hostName and componentName
   * @param {String} state - new state to update
   */
  updateComponentsState: function (components, state) {
    components.forEach(function (component) {
      App.ajax.send({
        name: 'common.host.host_component.update',
        sender: this,
        data: {
          hostName: component.hostName,
          serviceName: component.serviceName,
          componentName: component.componentName,
          HostRoles: {
            state: state
          },
          taskNum: components.length
        },
        success: 'startPolling',
        error: 'onTaskError'
      });
    }, this)
  },

  startPolling: function (data) {
    if (data) {
      this.get('currentRequestIds').push(data.Requests.id);
      var tasksCount = arguments[2].taskNum || 1;
      if (tasksCount === this.get('currentRequestIds').length) {
        this.setRequestIds(this.get('currentTaskId'), this.get('currentRequestIds'));
        this.doPolling();
      }
    } else {
      this.onTaskCompleted();
    }
  },

  doPolling: function () {
    this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
    var requestIds = this.get('currentRequestIds');
    this.set('logs', []);
    for (var i = 0; i < requestIds.length; i++) {
      App.ajax.send({
        name: 'background_operations.get_by_request',
        sender: this,
        data: {
          requestId: requestIds[i]
        },
        success: 'parseLogs',
        error: 'onTaskError'
      });
    }
  },

  parseLogs: function (logs) {
    this.get('logs').pushObject(logs.tasks);
    if (this.get('currentRequestIds').length === this.get('logs').length) {
      var tasks = [];
      this.get('logs').forEach(function (logs) {
        tasks.pushObjects(logs);
      }, this);
      var self = this;
      var currentTaskId = this.get('currentTaskId');
      if (!tasks.someProperty('Tasks.status', 'PENDING') && !tasks.someProperty('Tasks.status', 'QUEUED') && !tasks.someProperty('Tasks.status', 'IN_PROGRESS')) {
        this.set('currentRequestIds', []);
        if (tasks.someProperty('Tasks.status', 'FAILED') || tasks.someProperty('Tasks.status', 'TIMEDOUT') || tasks.someProperty('Tasks.status', 'ABORTED')) {
          this.setTaskStatus(currentTaskId, 'FAILED');
        } else {
          this.setTaskStatus(currentTaskId, 'COMPLETED');
        }
      } else {
        var actionsPerHost = tasks.length;
        var completedActions = tasks.filterProperty('Tasks.status', 'COMPLETED').length
          + tasks.filterProperty('Tasks.status', 'FAILED').length
          + tasks.filterProperty('Tasks.status', 'ABORTED').length
          + tasks.filterProperty('Tasks.status', 'TIMEDOUT').length;
        var queuedActions = tasks.filterProperty('Tasks.status', 'QUEUED').length;
        var inProgressActions = tasks.filterProperty('Tasks.status', 'IN_PROGRESS').length;
        var progress = Math.floor(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsPerHost * 100);
        this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
        window.setTimeout(function () {
          self.doPolling();
        }, self.POLL_INTERVAL);
      }
    }
  },

  showHostProgressPopup: function (event) {
    if (!['IN_PROGRESS', 'FAILED', 'COMPLETED'].contains(Em.get(event.context, 'status')) || !event.contexts[0].requestIds.length) {
      return;
    }
    var popupTitle = event.contexts[0].title,
     requestIds = event.contexts[0].requestIds,
     stageId = event.contexts[0].stageId,
     hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
    hostProgressPopupController.initPopup(popupTitle, requestIds, this, true, stageId);
  },

  done: function () {
    if (!this.get('isSubmitDisabled')) {
      this.set('isSubmitDisabled', true);
      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
      App.router.send('next');
    }
  },

  back: function () {
    if (!this.get('isBackButtonDisabled')) {
      this.set('isBackButtonDisabled', true);
      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
      App.router.send('back');
    }
  },

  /**
   * Delete component on single hosts.
   *
   * @method deleteComponent
   * @param {string} componentName - name of the component
   * @param {string} hostName - host from where components should be deleted
   */
  deleteComponent: function (componentName, hostName) {
    App.ajax.send({
      name: 'common.delete.host_component',
      sender: this,
      data: {
        componentName: componentName,
        hostName: hostName
      },
      success: 'onTaskCompleted',
      error: 'onDeleteHostComponentsError'
    });
  },

  onDeleteHostComponentsError: function (error) {
    // If the component does not exist on the host, NoSuchResourceException is thrown.
    // If NoSuchResourceException is thrown, there is no action required and operation should continue.
    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.NoSuchResourceException') !== -1) {
      this.onTaskCompleted();
    } else {
      this.onTaskError();
    }
  },

  /**
   * Same as <code>createComponent</code> but with kdc session check and status changes
   * when KDC auth dialog dissmised.
   *
   * @see createComponent
   */
  createInstallComponentTask: function(componentName, hostName, serviceName, options) {
    var self = this;
    App.get('router.mainAdminKerberosController').getKDCSessionState(function() {
      self.createComponent(componentName, hostName, serviceName);
    }, function() {
      self.onTaskError();
    });
  }
});
