/**
 * 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 date = require('utils/date/date');
var dataUtils = require('utils/data_manipulation');

/**
 * Host information shown in the operations popup
 * @typedef {Em.Object} wrappedHost
 * @property {string} name
 * @property {string} publicName
 * @property {string} displayName
 * @property {number} progress
 * @property {boolean} isInProgress
 * @property {string} serviceName
 * @property {string} status
 * @property {number} isVisible
 * @property {string} icon
 * @property {string} barColor
 * @property {string} barWidth
 */

/**
 * Task information shown in the operations popup
 * @typedef {Em.Object} wrappedTask
 * @property {string} id
 * @property {string} hostName
 * @property {string} command
 * @property {string} commandDetail
 * @property {string} status
 * @property {string} role
 * @property {string} stderr
 * @property {string} stdout
 * @property {number} request_id
 * @property {boolean} isVisible
 * @property {string} startTime
 * @property {string} duration
 * @property {string} icon
 */

/**
 * Service information shown in the operations popup
 * @typedef {Em.Object} wrappedService
 * @property {string} id
 * @property {string} displayName
 * @property {string} progress
 * @property {string} status
 * @property {boolean} isRunning
 * @property {string} name
 * @property {boolean} isVisible
 * @property {string} startTime
 * @property {string} duration
 * @property {string} icon
 * @property {string} barColor
 * @property {boolean} isInProgress
 * @property {string} barWidth
 * @property {number} sourceRequestScheduleId
 * @property {string} contextCommand
 */

/**
 * App.HostPopup is for the popup that shows up upon clicking already-performed or currently-in-progress operations
 * Allows to abort executing operations
 *
 * @type {Em.Object}
 * @class {HostPopup}
 */
App.HostPopup = Em.Object.create({

  name: 'hostPopup',

  /**
   * @type {object[]}
   */
  servicesInfo: [],

  /**
   * @type {wrappedHost[]}
   */
  hosts: [],

  /**
   * @type {?object[]}
   */
  inputData: null,

  /**
   * @type {string}
   */
  serviceName: '',

  /**
   * @type {?Number}
   */
  currentServiceId: null,

  /**
   * @type {?Number}
   */
  previousServiceId: null,

  /**
   * @type {string}
   */
  popupHeaderName: '',

  operationInfo: null,

  /**
   * @type {?App.Controller}
   */
  dataSourceController: null,

  /**
   * @type {bool}
   */
  isBackgroundOperations: false,

  /**
   * @type {?string}
   */
  currentHostName: null,

  /**
   * @type {?App.ModalPopup}
   */
  isPopup: null,

  /**
   * @type {object}
   */
  detailedProperties: {
    stdout: 'stdout',
    stderr: 'stderr',
    outputLog: 'output_log',
    errorLog: 'error_log'
  },

  /**
   * @type {object}
   */
  barColorMap: {
    'FAILED': 'progress-danger',
    'ABORTED': 'progress-warning',
    'TIMEDOUT': 'progress-warning',
    'IN_PROGRESS': 'progress-info',
    'COMPLETED': 'progress-success'
  },

  /**
   * map to get css class with styles by service status
   *
   * @type {object}
   */
  statusesStyleMap: {
    'FAILED': ['FAILED', 'icon-exclamation-sign', 'progress-danger', false],
    'ABORTED': ['ABORTED', 'icon-minus', 'progress-warning', false],
    'TIMEDOUT': ['TIMEDOUT', 'icon-time', 'progress-warning', false],
    'IN_PROGRESS': ['IN_PROGRESS', 'icon-cogs', 'progress-info', true],
    'COMPLETED': ['SUCCESS', 'icon-ok', 'progress-success', false]
  },

  /**
   * View with "Abort Request"-button
   *
   * @type {Em.View}
   */
  abortIcon: Em.View.extend({
    tagName: 'i',
    classNames: ['abort-icon', 'icon-remove-circle', 'pointer'],
    click: function () {
      this.get('controller').abortRequest(this.get('servicesInfo'));
      return false;
    },
    didInsertElement: function () {
      App.tooltip($(this.get('element')), {
        placement: "top",
        title: Em.I18n.t('hostPopup.bgop.abortRequest.title')
      });
    },
    willDestroyElement: function () {
      $(this.get('element')).tooltip('destroy');
    }
  }),

  /**
   * View with status icon (and tooltip on it)
   *
   * @type {Em.View}
   */
  statusIcon: Em.View.extend({
    tagName: 'i',
    classNames: ["service-status"],
    classNameBindings: ['servicesInfo.status', 'servicesInfo.icon', 'additionalClass'],
    attributeBindings: ['data-original-title'],
    'data-original-title': function () {
      return this.get('servicesInfo.status');
    }.property('servicesInfo.status'),
    didInsertElement: function () {
      App.tooltip($(this.get('element')));
    },
    willDestroyElement: function () {
      $(this.get('element')).tooltip('destroy');
    }
  }),

  /**
   * Determines if background operation can be aborted depending on its status
   *
   * @param status
   * @returns {boolean}
   */
  isAbortableByStatus: function (status) {
    var statuses = this.get('statusesStyleMap');
    return !Em.keys(statuses).contains(status) || status === 'IN_PROGRESS';
  },

  /**
   * Send request to abort operation
   *
   * @method abortRequest
   */
  abortRequest: function (serviceInfo) {
    var requestName = serviceInfo.get('name');
    var self = this;
    App.showConfirmationPopup(function () {
      serviceInfo.set('isAbortable', false);
      return App.ajax.send({
        name: 'background_operations.abort_request',
        sender: self,
        data: {
          requestId: serviceInfo.get('id'),
          requestName: requestName,
          serviceInfo: serviceInfo
        },
        success: 'abortRequestSuccessCallback',
        error: 'abortRequestErrorCallback'
      });
    }, Em.I18n.t('hostPopup.bgop.abortRequest.confirmation.body').format(requestName));
    return false;
  },

  /**
   * Method called on successful sending request to abort operation
   *
   * @return {App.ModalPopup}
   * @method abortRequestSuccessCallback
   */
  abortRequestSuccessCallback: function (response, request, data) {
    return App.ModalPopup.show({
      header: Em.I18n.t('hostPopup.bgop.abortRequest.modal.header'),
      encodeBody: false,
      body: Em.I18n.t('hostPopup.bgop.abortRequest.modal.body').format(data.requestName),
      secondary: null
    });
  },

  /**
   * Method called on unsuccessful sending request to abort operation
   *
   * @method abortRequestErrorCallback
   */
  abortRequestErrorCallback: function (xhr, textStatus, error, opt, data) {
    data.serviceInfo.set('isAbortable', this.isAbortableByStatus(data.serviceInfo.status));
    App.ajax.defaultErrorHandler(xhr, opt.url, 'PUT', xhr.status);
  },

  /**
   * Entering point of this component
   *
   * @param {String} serviceName
   * @param {Object} controller
   * @param {Boolean} isBackgroundOperations
   * @param {Integer} requestId
   * @method initPopup
   */
  initPopup: function (serviceName, controller, isBackgroundOperations, requestId) {
    if (App.get('isClusterUser')) return;
    if (!isBackgroundOperations) {
      this.clearHostPopup();
      this.set("popupHeaderName", serviceName);
    }

    this.setProperties({
      currentServiceId: requestId,
      serviceName: serviceName,
      dataSourceController: controller,
      isBackgroundOperations: isBackgroundOperations,
      inputData: this.get("dataSourceController.services")
    });

    if (isBackgroundOperations) {
      this.onServiceUpdate();
    } else {
      this.onHostUpdate();
    }
    return this.createPopup();
  },

  /**
   * clear info popup data
   *
   * @method clearHostPopup
   */
  clearHostPopup: function () {
    this.setProperties({
      servicesInfo: [],
      host: null,
      inputData: null,
      serviceName: '',
      currentServiceId: null,
      previousServiceId: null,
      popupHeaderName: '',
      dataSourceController: null,
      currentHostName: null
    });
    if(this.get('isPopup')) {
      this.get('isPopup').remove();
    }
  },

  /**
   * Depending on tasks status
   *
   * @param {object[]} tasks
   * @return {*[]} [Status, Icon type, Progressbar color, is IN_PROGRESS]
   * @method getStatus
   */
  getStatus: function (tasks) {
    var isCompleted = true;
    var tasksLength = tasks.length;
    for (var i = 0; i < tasksLength; i++) {
      var taskStatus = tasks[i].Tasks.status;
      if (taskStatus !== 'COMPLETED') {
        isCompleted = false;
      }
      if (taskStatus === 'FAILED') {
        return ['FAILED', 'icon-exclamation-sign', 'progress-danger', false];
      }
      if (taskStatus === 'ABORTED') {
        return ['ABORTED', 'icon-minus', 'progress-warning', false];
      }
      if (taskStatus === 'TIMEDOUT') {
        return ['TIMEDOUT', 'icon-time', 'progress-warning', false];
      }
      if (taskStatus === 'IN_PROGRESS') {
        return ['IN_PROGRESS', 'icon-cogs', 'progress-info', true]
      }
    }
    if (isCompleted) {
      return ['SUCCESS', 'icon-ok', 'progress-success', false];
    }
    return ['PENDING', 'icon-cog', 'progress-info', true];
  },

  /**
   * Progress of host or service depending on tasks status
   * If no tasks, progress is 0
   *
   * @param {?object[]} tasks
   * @return {Number} percent of completion
   * @method getProgress
   */
  getProgress: function (tasks) {
    if (!tasks || !tasks.length) {
      return 0;
    }

    var groupedByStatus = dataUtils.groupPropertyValues(tasks, 'Tasks.status');

    var completedActions = Em.getWithDefault(groupedByStatus, 'COMPLETED.length', 0) +
      Em.getWithDefault(groupedByStatus, 'FAILED.length', 0) +
      Em.getWithDefault(groupedByStatus, 'ABORTED.length', 0) +
      Em.getWithDefault(groupedByStatus, 'TIMEDOUT.length', 0);
    var queuedActions = Em.getWithDefault(groupedByStatus, 'QUEUED.length', 0);
    var inProgressActions = Em.getWithDefault(groupedByStatus, 'IN_PROGRESS.length', 0);

    return Math.ceil((queuedActions * 0.09 + inProgressActions * 0.35 + completedActions ) / tasks.length * 100);
  },

  /**
   * Count number of operations for select box options
   *
   * @param {?Object[]} obj
   * @param {progressPopupCategoryObject[]} categories
   * @method setSelectCount
   */
  setSelectCount: function (obj, categories) {
    if (!obj) {
      return;
    }
    var groupedByStatus = dataUtils.groupPropertyValues(obj, 'status');

    categories.findProperty("value", 'all').set("count", obj.length);
    categories.findProperty("value", 'pending').set("count", Em.getWithDefault(groupedByStatus, 'pending.length', 0) + Em.getWithDefault(groupedByStatus, 'queued.length', 0));
    categories.findProperty("value", 'in_progress').set("count", Em.getWithDefault(groupedByStatus, 'in_progress.length', 0));
    categories.findProperty("value", 'failed').set("count", Em.getWithDefault(groupedByStatus, 'failed.length', 0));
    categories.findProperty("value", 'completed').set("count", Em.getWithDefault(groupedByStatus, 'success.length', 0) + Em.getWithDefault(groupedByStatus, 'completed.length', 0));
    categories.findProperty("value", 'aborted').set("count", Em.getWithDefault(groupedByStatus, 'aborted.length', 0));
    categories.findProperty("value", 'timedout').set("count", Em.getWithDefault(groupedByStatus, 'timedout.length', 0));
  },

  /**
   * For Background operation popup calculate number of running Operations, and set popup header
   *
   * @param {bool} isServiceListHidden
   * @method setBackgroundOperationHeader
   */
  setBackgroundOperationHeader: function (isServiceListHidden) {
    if (this.get('isBackgroundOperations') && !isServiceListHidden) {
      var numRunning = App.router.get('backgroundOperationsController.allOperationsCount');
      this.set("popupHeaderName", numRunning + Em.I18n.t('hostPopup.header.postFix').format(numRunning === 1 ? "" : "s"));
    }
  },

  /**
   * Create services obj data structure for popup
   * Set data for services
   *
   * @param {bool} isServiceListHidden
   * @method onServiceUpdate
   */
  onServiceUpdate: function (isServiceListHidden) {
    if (this.get('isBackgroundOperations') && this.get("inputData")) {
      var servicesInfo = this.get("servicesInfo");
      var currentServices = [];
      this.get("inputData").forEach(function (service, index) {
        var updatedService;
        var id = service.id;
        currentServices.push(id);
        var existedService = servicesInfo.findProperty('id', id);
        updatedService = existedService;
        if (existedService) {
          updatedService = this.updateService(existedService, service);
        }
        else {
          updatedService = this.createService(service);
          servicesInfo.insertAt(index, updatedService);
        }
        updatedService.set('isAbortable', App.isAuthorized('SERVICE.START_STOP') && this.isAbortableByStatus(service.status));
      }, this);
      this.removeOldServices(servicesInfo, currentServices);
      this.setBackgroundOperationHeader(isServiceListHidden);
    }
  },

  /**
   * Create service object from transmitted data
   *
   * @param {object} service
   * @return {wrappedService}
   * @method createService
   */
  createService: function (service) {
    var statuses = this.get('statusesStyleMap');
    var pendingStatus = ['PENDING', 'icon-cog', 'progress-info', true];
    var status = statuses[service.status] || pendingStatus;
    return Em.Object.create({
      id: service.id,
      displayName: service.displayName,
      progress: service.progress,
      status: App.format.taskStatus(status[0]),
      isRunning: service.isRunning,
      name: service.name,
      isVisible: true,
      startTime: date.startTime(service.startTime),
      duration: date.durationSummary(service.startTime, service.endTime),
      icon: status[1],
      barColor: status[2],
      isInProgress: status[3],
      barWidth: "width:" + service.progress + "%;",
      sourceRequestScheduleId: service.sourceRequestScheduleId,
      contextCommand: service.contextCommand
    });
  },

  /**
   * Update properties of existed service with new data
   *
   * @param {wrappedService} service
   * @param {object} newData
   * @returns {wrappedService}
   * @method updateService
   */
  updateService: function (service, newData) {
    var statuses = this.get('statusesStyleMap');
    var pendingStatus = ['PENDING', 'icon-cog', 'progress-info', true];
    var status = statuses[newData.status] || pendingStatus;
    return service.setProperties({
      progress: newData.progress,
      status: App.format.taskStatus(status[0]),
      isRunning: newData.isRunning,
      startTime: date.startTime(newData.startTime),
      duration: date.durationSummary(newData.startTime, newData.endTime),
      icon: status[1],
      barColor: status[2],
      isInProgress: status[3],
      barWidth: "width:" + newData.progress + "%;",
      sourceRequestScheduleId: newData.get('sourceRequestScheduleId'),
      contextCommand: newData.get('contextCommand')
    });
  },

  /**
   * remove old requests
   * as API returns 10, or  20 , or 30 ...etc latest request, the requests that absent in response should be removed
   *
   * @param {wrappedService[]} services
   * @param {number[]} currentServicesIds
   * @method removeOldServices
   */
  removeOldServices: function (services, currentServicesIds) {
    for (var i = 0, l = services.length; i < l; i++) {
      if (!currentServicesIds.contains(services[i].id)) {
        services.splice(i, 1);
        i--;
        l--;
      }
    }
  },

  /**
   * Wrap task as Ember-object
   *
   * @param {Object} _task
   * @return {wrappedTask}
   * @method createTask
   */
  createTask: function (_task) {
    return Em.Object.create({
      id: _task.Tasks.id,
      hostName: _task.Tasks.host_name,
      command: _task.Tasks.command.toLowerCase() === 'service_check' ? '' : _task.Tasks.command.toLowerCase(),
      commandDetail: App.format.commandDetail(_task.Tasks.command_detail, _task.Tasks.request_inputs),
      status: App.format.taskStatus(_task.Tasks.status),
      role: App.format.role(_task.Tasks.role, false),
      stderr: _task.Tasks.stderr,
      stdout: _task.Tasks.stdout,
      request_id: _task.Tasks.request_id,
      isVisible: true,
      startTime: date.startTime(_task.Tasks.start_time),
      duration: date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time),
      icon: function () {
        var statusIconMap = {
          'pending': 'icon-cog',
          'queued': 'icon-cog',
          'in_progress': 'icon-cogs',
          'completed': 'icon-ok',
          'failed': 'icon-exclamation-sign',
          'aborted': 'icon-minus',
          'timedout': 'icon-time'
        };
        return statusIconMap[this.get('status')] || 'icon-cog';
      }.property('status')
    });
  },

  /**
   * Create hosts and tasks data structure for popup
   * Set data for hosts and tasks
   *
   * @method onHostUpdate
   */
  onHostUpdate: function () {
    var self = this;
    if (this.get("inputData")) {
      var hostsMap = this._getHostsMap();
      var existedHosts = self.get('hosts');

      if (existedHosts && existedHosts.length && this.get('currentServiceId') === this.get('previousServiceId')) {
        this._processingExistingHostsWithSameService(hostsMap);
      }
      else {
        var hostsArr = this._hostMapProcessing(hostsMap);
        hostsArr = hostsArr.sortProperty('name');
        hostsArr.setEach("serviceName", this.get("serviceName"));
        self.set("hosts", hostsArr);
        self.set('previousServiceId', this.get('currentServiceId'));
      }
    }
    var operation = this.get('servicesInfo').findProperty('name', this.get('serviceName'));
    this.set('operationInfo', !operation || operation && operation.get('progress') === 100 ? null : operation);
  },

  /**
   * Generate hosts map for further processing <code>inputData</code>
   *
   * @returns {object}
   * @private
   * @method _getHostsMap
   */
  _getHostsMap: function () {
    var hostsData;
    var hostsMap = {};
    var inputData = this.get('inputData');
    if (this.get('isBackgroundOperations') && this.get("currentServiceId")) {
      //hosts popup for Background Operations
      hostsData = inputData.findProperty("id", this.get("currentServiceId"));
    }
    else {
      if (this.get("serviceName")) {
        //hosts popup for Wizards
        hostsData = inputData.findProperty("name", this.get("serviceName"));
      }
    }

    if (hostsData) {
      if (hostsData.hostsMap) {
        //hosts data come from Background Operations as object map
        hostsMap = hostsData.hostsMap;
      }
      else {
        if (hostsData.hosts) {
          //hosts data come from Wizard as array
          hostsMap = hostsData.hosts.toMapByProperty('name');
        }
      }
    }
    return hostsMap;
  },

  /**
   *
   * @param {object} hostsMap
   * @returns {wrappedHost[]}
   * @private
   * @method _hostMapProcessing
   */
  _hostMapProcessing: function (hostsMap) {
    var self = this;
    var hostsArr = [];
    for (var hostName in hostsMap) {
      if (!hostsMap.hasOwnProperty(hostName)) {
        continue;
      }
      var _host = hostsMap[hostName];
      var tasks = _host.logTasks;
      var hostInfo = Em.Object.create({
        name: hostName,
        publicName: _host.publicName,
        displayName: Em.computed.truncate('name', 43, 40),
        progress: 0,
        status: App.format.taskStatus("PENDING"),
        serviceName: _host.serviceName,
        isVisible: true,
        icon: "icon-cog",
        barColor: "progress-info",
        barWidth: "width:0%;"
      });

      if (tasks.length) {
        tasks = tasks.sortProperty('Tasks.id');
        var hostStatus = self.getStatus(tasks);
        var hostProgress = self.getProgress(tasks);
        hostInfo.setProperties({
          status: App.format.taskStatus(hostStatus[0]),
          icon: hostStatus[1],
          barColor: hostStatus[2],
          isInProgress: hostStatus[3],
          progress: hostProgress,
          barWidth: "width:" + hostProgress + "%;"
        });
      }
      hostInfo.set('logTasks', tasks);
      hostsArr.push(hostInfo);
    }
    return hostsArr;
  },

  /**
   *
   * @param {object} hostsMap
   * @private
   * @method _processingExistingHostsWithSameService
   */
  _processingExistingHostsWithSameService: function (hostsMap) {
    var self = this;
    var existedHosts = self.get('hosts');
    var detailedProperties = this.get('detailedProperties');
    var detailedPropertiesKeys = Em.keys(detailedProperties);
    existedHosts.forEach(function (host) {
      var newHostInfo = hostsMap[host.get('name')];
      //update only hosts with changed tasks or currently opened tasks of host
      if (newHostInfo &&
          (!this.get('isBackgroundOperations') ||
            newHostInfo.isModified ||
            this.get('currentHostName') === host.get('name'))) {
        var hostStatus = self.getStatus(newHostInfo.logTasks);
        var hostProgress = self.getProgress(newHostInfo.logTasks);
        host.setProperties({
          status: App.format.taskStatus(hostStatus[0]),
          icon: hostStatus[1],
          barColor: hostStatus[2],
          isInProgress: hostStatus[3],
          progress: hostProgress,
          barWidth: "width:" + hostProgress + "%;",
          logTasks: newHostInfo.logTasks
        });
        var existTasks = host.get('tasks');
        if (existTasks) {
          newHostInfo.logTasks.forEach(function (_task) {
            var existTask = existTasks.findProperty('id', _task.Tasks.id);
            if (existTask) {
              var status = _task.Tasks.status;
              detailedPropertiesKeys.forEach(function (key) {
                var name = detailedProperties[key];
                var value = _task.Tasks[name];
                if (!Em.isNone(value)) {
                  existTask.set(key, value);
                }
              }, this);
              existTask.setProperties({
                status: App.format.taskStatus(status),
                startTime: date.startTime(_task.Tasks.start_time),
                duration: date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time)
              });
              existTask = self._handleRebalanceHDFS(_task, existTask);
            }
            else {
              existTasks.pushObject(this.createTask(_task));
            }
          }, this);
        }
      }
    }, this);
  },

  /**
   * Custom processing for "Rebalance HDFS"-task
   *
   * @param {object} task
   * @param {object} existTask
   * @returns {object}
   * @private
   * @method _handleRebalanceHDFS
   */
  _handleRebalanceHDFS: function (task, existTask) {
    var barColorMap = this.get('barColorMap');
    var isRebalanceHDFSTask = task.Tasks.command === 'CUSTOM_COMMAND' && task.Tasks.custom_command_name === 'REBALANCEHDFS';
    existTask.set('isRebalanceHDFSTask', isRebalanceHDFSTask);
    if (isRebalanceHDFSTask) {
      var structuredOut = task.Tasks.structured_out || {};
      var status = task.Tasks.status;
      existTask.setProperties({
        dataMoved: structuredOut.dataMoved || '0',
        dataLeft: structuredOut.dataLeft || '0',
        dataBeingMoved: structuredOut.dataBeingMoved || '0',
        barColor: barColorMap[status],
        isInProgress: status === 'IN_PROGRESS',
        isNotComplete: ['QUEUED', 'IN_PROGRESS'].contains(status),
        completionProgressStyle: 'width:' + (structuredOut.completePercent || 0) * 100 + '%;',
        command: task.Tasks.command,
        custom_command_name: task.Tasks.custom_command_name
      });
    }
    return existTask;
  },

  /**
   * Show popup
   *
   * @return {App.ModalPopup} PopupObject For testing purposes
   */
  createPopup: function () {
    var self = this;
    var isBackgroundOperations = this.get('isBackgroundOperations');

    this.set('isPopup', App.ModalPopup.show({

      /**
       * @type {boolean}
       */
      isLogWrapHidden: true,

      /**
       * @type {boolean}
       */
      isTaskListHidden: true,

      /**
       * @type {boolean}
       */
      isHostListHidden: true,

      /**
       * @type {boolean}
       */
      isServiceListHidden: false,

      /**
       * @type {boolean}
       */
      isHideBodyScroll: true,

      /**
       * no need to track is it loaded when popup contain only list of hosts
       * @type {bool}
       */
      isLoaded: !isBackgroundOperations,

      /**
       * is BG-popup opened
       * @type {bool}
       */
      isOpen: false,

      /**
       * @type {object}
       */
      detailedProperties: self.get('detailedProperties'),

      isVisible: function() {
        return !(App.get('isClusterUser') && isBackgroundOperations);
      }.property('App.isClusterUser'),

      didInsertElement: function () {
        this._super();
        this.set('isOpen', true);
      },

      /**
       * @type {Em.View}
       */
      headerClass: Em.View.extend({
        controller: this,
        template: Em.Handlebars.compile('{{popupHeaderName}} ' +
          '{{#unless view.parentView.isHostListHidden}}{{#if controller.operationInfo.isAbortable}}' +
          '{{view controller.abortIcon servicesInfoBinding="controller.operationInfo"}}' +
          '{{/if}}{{/unless}}')
      }),

      /**
       * @type {Em.View}
       */
      footerClass: Em.View.extend({
        classNames: ["modal-footer"],
        templateName: require('templates/common/host_progress_popup_footer')
      }),

      /**
       * @type {String[]}
       */
      classNames: ['sixty-percent-width-modal', 'host-progress-popup', 'full-height-modal'],

      /**
       * Auto-display BG-popup
       *
       * @type {bool}
       */
      isNotShowBgChecked: null,

      /**
       * Save user pref about auto-display BG-popup
       *
       * @method updateNotShowBgChecked
       */
      updateNotShowBgChecked: function () {
        var curVal = !this.get('isNotShowBgChecked');
        if (!App.get('testMode')) {
          App.router.get('userSettingsController').postUserPref('show_bg', curVal);
        }
      }.observes('isNotShowBgChecked'),

      autoHeight: false,

      /**
       * @method closeModelPopup
       */
      closeModelPopup: function () {
        this.set('isOpen', false);
        if (isBackgroundOperations) {
          $(this.get('element')).detach();
          App.router.get('backgroundOperationsController').set('levelInfo.name', 'REQUESTS_LIST');
        } else {
          this.hide();
          self.set('isPopup', null);
        }
      },

      onPrimary: function () {
        this.closeModelPopup();
      },

      onClose: function () {
        this.closeModelPopup();
      },

      secondary: null,

      bodyClass: App.HostProgressPopupBodyView.extend({
        controller: self
      })

    }));

    return this.get('isPopup');
  }
});
