/**
 * 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 dbInfo = require('data/db_properties_info') || {};

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

/**
 * Abstract view for config fields.
 * Add popover support to control
 */
App.ServiceConfigPopoverSupport = Ember.Mixin.create({

  /**
   * Config object. It will instance of App.ServiceConfigProperty
   */
  serviceConfig: null,
  attributeBindings:['readOnly'],
  isPopoverEnabled: true,
  popoverPlacement: 'auto right',

  didInsertElement: function () {
    App.tooltip(this.$('[data-toggle=tooltip]'), {placement: 'top'});
    // if description for this serviceConfig not exist, then no need to show popover
    if (this.get('isPopoverEnabled') !== 'false' && this.get('serviceConfig.description')) {
      this.addPopover();
    }
  },

  /**
   * Element where popover is "appended"
   */
  elementForPopover: function () {
    return this.$();
  }.property(),

  /**
   * Add Popover for config-boxes
   *
   * @method addPopover
   */
  addPopover: function () {
    App.popover(this.get('elementForPopover'), {
      title: Em.I18n.t('installer.controls.serviceConfigPopover.title').format(
        this.get('serviceConfig.displayName'),
        (this.get('serviceConfig.displayName') === this.get('serviceConfig.name')) ? '' : this.get('serviceConfig.name')
      ),
      content: this.get('serviceConfig.description'),
      placement: this.get('popoverPlacement'),
      trigger: 'hover',
      html: true
    });
  },

  willDestroyElement: function() {
    this.$().popover('destroy');
  },

  readOnly: Em.computed.not('serviceConfig.isEditable')
});

App.SupportsDependentConfigs = Ember.Mixin.create({

  /**
   * method send request to check if some of dependent configs was changes
   * and in case there was changes shows popup with info about changed configs
   *
   * @param {App.ServiceConfigProperty} config
   * @param [controller]
   * @returns {$.Deferred}
   */
  sendRequestRorDependentConfigs: function(config, controller) {
    if (!config || (!config.get('isValid') && config.get('isNotDefaultValue'))) return $.Deferred().resolve().promise();
    controller = controller || this.get('controller');
    if (controller && ['mainServiceInfoConfigsController','wizardStep7Controller'].contains(controller.get('name'))) {
      var name = config.get('name');
      var saveRecommended = (config.get('value') === config.get('recommendedValue'));
      var type = App.config.getConfigTagFromFileName(config.get('filename'));
      var p = App.configsCollection.getConfig(App.config.configId(name, type));
      controller.removeCurrentFromDependentList(config, saveRecommended);
       if ((p && Em.get(p, 'propertyDependedBy.length') > 0)
         || (config.get('displayType') === 'user' && config.get('oldValue') !== config.get('value'))) {
         var old = config.get('oldValue');
         config.set('oldValue', config.get('value'));
         return controller.loadConfigRecommendations([{
           "type": type,
           "name": name,
           "old_value": Em.isNone(old) ? config.get('initialValue') : old
         }]);
      }
    }

    return $.Deferred().resolve().promise();
  },

  /**
   * Restore values for dependent configs by parent config info.
   * NOTE: If dependent config inherited from multiply configs its
   * value will be restored only when all parent configs are being restored.
   *
   * @param {App.ServiceConfigProperty} parentConfig
   */
  restoreDependentConfigs: function(parentConfig) {
    var controller = this.get('controller');
    var dependentConfigs = controller.get('recommendations');
    try {
      controller.set('recommendations', dependentConfigs.reject(function(item) {
        if (item.parentConfigs.contains(parentConfig.get('name'))) {
          if (item.parentConfigs.length > 1) {
            item.parentConfigs.removeObject(parentConfig.get('name'));
          } else {
            // reset property value
            var property = App.config.findConfigProperty(controller.get('stepConfigs'), item.propertyName, App.config.getOriginalFileName(item.fileName));
            if (property) {
              property.set('value', property.get('savedValue') || property.get('initialValue'));
            }
            return true;
          }
        }
        return false;
      }));
    } catch(e) {
      console.warn('Dependent properties popup was not cleared');
    }
  }

});

/**
 * mixin is used to send request for recommendations
 * when config value is updated by user
 */
App.ValueObserver = Em.Mixin.create(App.SupportsDependentConfigs, {

  selected: false,

  focusOut: function () {
    this.set('selected', false);
  },

  focusIn: function () {
    this.set('selected', true);
  },

  onValueUpdate: function () {
    if (!this.get('isVisible')) return;
    if (this.get('selected') || this.get('serviceConfig.changedViaUndoValue')) {
      var self = this, config = this.get('serviceConfig'),
        controller = this.get('controller');
      delay(function(){
        self.sendRequestRorDependentConfigs(config, controller);
      }, 500);
    }
  }.observes('serviceConfig.value')
});

/**
 * mixin is used to send request for recommendations
 * when config value is updated by user
 */
App.WidgetValueObserver = Em.Mixin.create(App.ValueObserver, {
  onValueUpdate: function () {
    if (this.get('selected')) {
      var self = this, config = this.get('config'),
        controller = this.get('controller');
      delay(function(){
        self.sendRequestRorDependentConfigs(config, controller);
      }, 500);
    }
  }.observes('config.value')
});

/**
 * mixin set class that serve as unique element identifier,
 * id not used in order to avoid collision with ember ids
 */
App.ServiceConfigCalculateId = Ember.Mixin.create({
  'data-qa': Ember.computed(function () {
    const config = this.get('config') && this.get('config.widget') ? this.get('config') : this.get('serviceConfig') || {};
    const configName = Em.get(config, 'name') || '';
    if (configName === 'content') {
      return Em.get(config, 'id') || '';
    }
    return configName;
  })
});

/**
 * Default input control
 * @type {*}
 */
App.ServiceConfigTextField = Ember.TextField.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.ValueObserver, {
  classNames: ['form-control'],
  valueBinding: 'serviceConfig.value',
  classNameBindings: 'textFieldClassName',
  placeholderBinding: 'serviceConfig.placeholder',

  //Set editDone true for last edited config text field parameter
  focusOut: function () {
    this._super();
    this.get('serviceConfig').set("editDone", true);
  },
  //Set editDone false for all current category config text field parameter
  focusIn: function () {
    this._super();
    if (!this.get('serviceConfig.isOverridden') && !this.get('serviceConfig.isComparison')) {
      if (this.get('parentView.categoryConfigsAll')) {
        this.get("parentView.categoryConfigsAll").setEach("editDone", false);
      }
    }
  },

  textFieldClassName: function () {
    if (this.get('serviceConfig.unit')) {
      return ['input-sm'];
    } else if (this.get('serviceConfig.displayType') === 'principal') {
      return ['col-md-12'];
    } else {
      return ['col-md-9 long-input'];
    }
  }.property('serviceConfig.displayType', 'serviceConfig.unit')

});

/**
 * Customized input control for user/group configs with corresponding uid/gid specified
 * @type {Em.View}
 */
App.ServiceConfigTextFieldUserGroupWithID = Ember.View.extend(App.ServiceConfigPopoverSupport, {
  valueBinding: 'serviceConfig.value',
  placeholderBinding: 'serviceConfig.savedValue',
  classNamesBindings: 'view.fullWidth::display-inline-block',
  isPopoverEnabled: 'false',

  fullWidth: false,

  templateName: require('templates/wizard/controls_service_config_usergroup_with_id'),

  isUIDGIDVisible: function () {
    var serviceConfigs = this.get('parentView').serviceConfigs;
    var overrideUid = serviceConfigs && serviceConfigs.findProperty('name', 'override_uid');
    //don't display the ugid field if there is no uid/gid for this property or override_uid is unchecked
    if (Em.isNone(this.get('serviceConfig.ugid')) || overrideUid && overrideUid.value === 'false') {
      return false;
    }

    var serviceName = this.get('serviceConfig').name.substr(0, this.get('serviceConfig').name.indexOf('_')).toUpperCase();
    if (serviceName === 'ZK') {
      serviceName = 'ZOOKEEPER';
    }
    if (serviceName === 'MAPRED') {
      serviceName = 'YARN';
    }
    //addServiceController and service already installed or Hadoop user group
    if (App.Service.find(serviceName).get('isLoaded') || serviceName === 'USER') {
      return false;
    }

    return this.get('parentView.isUIDGIDVisible');
  }.property('parentView.isUIDGIDVisible')
});

/**
 * Customized input control with Units type specified
 * @type {Em.View}
 */
App.ServiceConfigTextFieldWithUnit = Ember.View.extend(App.ServiceConfigPopoverSupport, App.ValueObserver, {
  valueBinding: 'serviceConfig.value',
  classNames: ['input-group', 'with-unit', 'col-md-4'],
  placeholderBinding: 'serviceConfig.savedValue',

  templateName: require('templates/wizard/controls_service_config_textfield_with_unit')
});

/**
 * Password control
 * @type {*}
 */
App.ServiceConfigPasswordField = Ember.View.extend(App.ServiceConfigPopoverSupport, {

  serviceConfig: null,

  placeholder: Em.I18n.t('form.item.placeholders.typePassword'),

  templateName: require('templates/common/configs/widgets/service_config_password_field'),

  classNames: ['password-field-wrapper'],

  readOnly: Em.computed.not('serviceConfig.isEditable'),

  keyPress: function (event) {
    if (event.keyCode == 13) {
      return false;
    }
  }

});

/**
 * Textarea control
 * @type {*}
 */
App.ServiceConfigTextArea = Ember.TextArea.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.ValueObserver, {

  valueBinding: 'serviceConfig.value',
  rows: 4,
  classNames: ['directories', 'form-control'],
  classNameBindings: ['widthClass'],
  widthClass: 'col-md-9'
});


/**
 * Special config type for Capacity Scheduler
 */
App.CapacitySceduler = App.ServiceConfigTextArea.extend({

  rows: 16,

  /**
   * specific property handling for cs
   *
   * @param {App.ServiceConfigProperty} config
   * @param [controller]
   * @returns {$.Deferred}
   * @override
   */
  sendRequestRorDependentConfigs: function(config, controller) {
    if (!config.get('isValid') && config.get('isNotDefaultValue')) return $.Deferred().resolve().promise();
    controller = controller || this.get('controller');
    if (controller && ['mainServiceInfoConfigsController','wizardStep7Controller'].contains(controller.get('name'))) {
      var schedulerConfigs = config.get('value').split('\n').map(function (_property) {
        return {
          "type": 'capacity-scheduler',
          "name": _property.split('=')[0]
        }
      });
      if (!schedulerConfigs.someProperty('name', 'capacity-scheduler')) {
        schedulerConfigs.push({
          "type": 'capacity-scheduler',
          "name": 'capacity-scheduler'
        });
      }
      return controller.loadConfigRecommendations(schedulerConfigs);
    }

    return $.Deferred().resolve().promise();
  }

});

/**
 * Textarea control for content type
 * @type {*}
 */
App.ServiceConfigTextAreaContent = Ember.TextArea.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.ValueObserver, {

  valueBinding: 'serviceConfig.value',
  rows: 20,
  classNames: ['col-md-10', 'form-control']
});

/**
 * Textarea control with bigger height
 * @type {*}
 */
App.ServiceConfigBigTextArea = App.ServiceConfigTextArea.extend(App.ServiceConfigCalculateId, {
  rows: 10
});

var checkboxConfigView = Ember.Checkbox.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.SupportsDependentConfigs, {
  allowedPairs: {
    'trueFalse': ["true", "false"],
    'YesNo': ["Yes", "No"],
    'YESNO': ["YES", "NO"],
    'yesNo': ["yes", "no"]
  },

  trueValue: true,
  falseValue: false,

  checked: false,

  elementForPopover: function () {
    return this.$().next();
  }.property(),

  /**
   * set appropriate config values pair
   * to define which value is positive (checked) property
   * and what value is negative (unchecked) property
   */
  didInsertElement: function() {
    var self = this;
    if (this.get('serviceConfig').isDestroyed) return;
    this._super();
    this.addObserver('serviceConfig.value', this, 'toggleChecker');
    var isInverted = this.get('serviceConfig.displayType') === 'boolean-inverted';
    Object.keys(this.get('allowedPairs')).forEach(function(key) {
      if (this.get('allowedPairs')[key].contains(this.get('serviceConfig.value'))) {
        this.set('trueValue', isInverted ? this.get('allowedPairs')[key][1] :this.get('allowedPairs')[key][0]);
        this.set('falseValue', isInverted ? this.get('allowedPairs')[key][0] :this.get('allowedPairs')[key][1]);
      }
    }, this);
    this.set('checked', this.get('serviceConfig.value') === this.get('trueValue'));
    this.propertyDidChange('checked');
    Em.run.next(function () {
      if (self.$()) {
        self.propertyDidChange('elementForPopover');
        self.addPopover();
      }
    });
  },

  willDestroyElement: function() {
    this.removeObserver('serviceConfig.value', this, 'checkedBinding');
  },

  /***
   * defines if checkbox value appropriate to the config value
   * @returns {boolean}
   */
  isNotAppropriateValue: function() {
    return this.get('serviceConfig.value') !== this.get(this.get('checked') + 'Value');
  },

  /**
   * change service config value if click on checkbox
   */
  toggleValue: function() {
    if (this.isNotAppropriateValue()){
      this.set('serviceConfig.value', this.get(this.get('checked') + 'Value'));
      this.get('serviceConfig').set("editDone", true);
      this.sendRequestRorDependentConfigs(this.get('serviceConfig'));

      //if the checkbox being toggled is the 'Have Ambari manage UIDs' in Misc Tab, show/hide uid/gid column accordingly
      if (this.get('serviceConfig.name') === 'override_uid') {
         this.set('parentView.isUIDGIDVisible', this.get('checked'));
      }
    }
  }.observes('checked'),

  /**
   * change checkbox value if click on undo
   */
  toggleChecker: function() {
    if (this.isNotAppropriateValue()) {
      this.set('checked', !this.get('checked'));
    }
  },

  disabled: Em.computed.not('serviceConfig.isEditable'),

  disabledDidChange: function() {
    if (!this.get('checkboxInstance')) return;
  }.observes('disabled'),

  //Set editDone false for all current category config text field parameter
  focusIn: function (event) {
    if (!this.get('serviceConfig.isOverridden') && !this.get('serviceConfig.isComparison')) {
      this.get("parentView.categoryConfigsAll").setEach("editDone", false);
    }
  }
});

/**
 * Checkbox control
 * @type {*}
 */
App.ServiceConfigCheckbox = App.CheckboxView.extend({
  classNames: ['display-inline-block'],
  classNameBindings: ['containerClassName'],
  containerClassName: 'checkbox',
  categoryConfigsAllBinding: 'parentView.categoryConfigsAll',
  checkboxView: checkboxConfigView.extend({
    serviceConfigBinding: 'parentView.serviceConfig',
    didInsertElement: function() {
      this.set('parentView.checkboxId', this.get('elementId'));
      this._super();
    }
  })
});

/**
 * Checkbox control which can hide or show dependent  properties
 * @type {*|void}
 */
App.ServiceConfigCheckboxWithDependencies = App.ServiceConfigCheckbox.extend({

  toggleDependentConfigs: function() {
    if (this.get('serviceConfig.dependentConfigPattern')) {
      if (this.get('serviceConfig.dependentConfigPattern') === "CATEGORY") {
        this.disableEnableCategoryConfigs();
      } else {
        this.showHideDependentConfigs();
      }
    }
  }.observes('checked'),

  disableEnableCategoryConfigs: function () {
    this.get('categoryConfigsAll').setEach('isEditable', this.get('checked'));
    this.set('serviceConfig.isEditable', true);
  },

  showHideDependentConfigs: function () {
    this.get('categoryConfigsAll').forEach(function (c) {
      if (c.get('name').match(this.get('serviceConfig.dependentConfigPattern')) && c.get('name') != this.get('serviceConfig.name'))
        c.set('isVisible', this.get('checked'))
    }, this);
  }
});

App.ServiceConfigRadioButtons = Ember.View.extend(App.ServiceConfigCalculateId, App.SupportsDependentConfigs, {
  templateName: require('templates/wizard/controls_service_config_radio_buttons'),

  didInsertElement: function () {
    // on page render, automatically populate JDBC URLs only for default database settings
    // so as to not lose the user's customizations on these fields
    if (this.get('hostNameProperty')) {
      this.get('hostNameProperty').set('isEditable', !this.get('isNewDb'));
    }
    if (['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name')) && !App.StackService.find(this.get('serviceConfig.serviceName')).get('isInstalled')) {
      if (this.get('isNewDb') || this.get('dontUseHandleDbConnection').contains(this.get('serviceConfig.name'))) {
        this.onOptionsChange();
      } else {
        if ((App.get('isHadoopWindowsStack') && this.get('inMSSQLWithIA')) || this.get('serviceConfig.name') === 'DB_FLAVOR') {
          this.onOptionsChange();
        }
      }
      this.handleDBConnectionProperty();
    }
  },

  /**
   * Radio buttons that are not DB options and should not trigger any observer or change any other property's value
   * Ranger service -> "Authentication method" property is an example for non DB related radio button
   */
  nonDBRadioButtons: function() {
    return this.get('dontUseHandleDbConnection').without('DB_FLAVOR');
  }.property('dontUseHandleDbConnection'),

  /**
   * properties with these names don'use handleDBConnectionProperty method
   */
  dontUseHandleDbConnection: function () {
    // functionality added in Ranger 0.5
    // remove DB_FLAVOR so it can handle DB Connection checks
    var rangerService = App.StackService.find().findProperty('serviceName', 'RANGER');
    var rangerVersion = rangerService ? rangerService.get('serviceVersion') : '';
    if (rangerVersion && rangerVersion.split('.')[0] < 1 && rangerVersion.split('.')[1] < 5) {
      return ['DB_FLAVOR', 'authentication_method'];
    }
    return ['ranger.authentication.method'];
  }.property('App.currentStackName'),

  serviceConfig: null,
  categoryConfigsAll: null,

  /**
   * defines if new db is selected;
   * @type {boolean}
   */
  isNewDb: function() {
    return /New /g.test(this.get('serviceConfig.value'));
  }.property('serviceConfig.serviceName', 'serviceConfig.value'),

  /**
   * defines if 'Existing MSSQL Server database with integrated authentication' is selected
   * in this case some properties can have different behaviour
   * @type {boolean}
   */
  inMSSQLWithIA: Em.computed.equal('serviceConfig.value', 'Existing MSSQL Server database with integrated authentication'),

  /**
   * Radio button has very uncomfortable values for managing it's state
   * so it's better to use code values that easier to manipulate. Ex:
   * "Existing MySQL Database" transforms to "MYSQL"
   * @type {string}
   */
  getDbTypeFromRadioValue: function() {
    var currentValue = this.get('serviceConfig.value');
    /** TODO: Remove SQLA from the list of databases once Ranger DB_FLAVOR=SQLA is replaced with SQL Anywhere */
    var databases = /MySQL|Postgres|Oracle|Derby|MSSQL|SQLA|Anywhere/gi;
    if (this.get('inMSSQLWithIA')) {
      return 'MSSQL2';
    } else {
      var matches = currentValue.match(databases);
      if (matches) {
        return currentValue.match(databases)[0].toUpperCase();
      } else {
        return "MYSQL";
      }
    }
  }.property('serviceConfig.serviceName', 'serviceConfig.value'),

  onOptionsChange: function () {
    if (!this.get('nonDBRadioButtons').contains(this.get('serviceConfig.name'))) {
      /** if new db is selected host name must be same as master of selected service (and can't be changed)**/
      this.handleSpecialUserPassProperties();
    }
  }.observes('databaseProperty.value', 'hostNameProperty.value', 'serviceConfig.value'),

  name: function () {
    var name = this.get('serviceConfig.radioName');
    if (!this.get('serviceConfig.isOriginalSCP')) {
      if (this.get('serviceConfig.isComparison')) {
        var version = this.get('serviceConfig.compareConfigs') ? this.get('controller.selectedVersion') : this.get('version');
        name += '-v' + version;
      } else {
        var group = this.get('serviceConfig.group.name');
        name += '-' + group;
      }
    }
    return name;
  }.property('serviceConfig.radioName'),

  /**
   * Just property object for database name
   * @type {App.ServiceConfigProperty}
   */
  databaseProperty: function () {
    return this.getPropertyByType('db_name');
  }.property('serviceConfig.serviceName'),

  /**
   * Just property object for host name
   * @type {App.ServiceConfigProperty}
   */
  hostNameProperty: function () {
    var host = this.getPropertyByType('host_name');
    if (host && !host.get('value')) {
      if (host.get('savedValue')) {
        host.set('value', host.get('savedValue'));
      } else if (host.get('recommendedValue')) {
        host.set('value', host.get('recommendedValue'));
      }
    }
    return host;
  }.property('serviceConfig.serviceName', 'serviceConfig.value'),

  /**
   * Just property object for database name
   * @type {App.ServiceConfigProperty}
   */
  userProperty: function () {
    return this.getPropertyByType('user_name');
  }.property('serviceConfig.serviceName'),

  /**
   * Just property object for database name
   * @type {App.ServiceConfigProperty}
   */
  passwordProperty: function () {
    return this.getPropertyByType('password');
  }.property('serviceConfig.serviceName'),

  /**
   *
   * @param propertyType
   * @returns {*}
   */
  getDefaultPropertyValue: function(propertyType) {
    var dbProperties = dbInfo.dpPropertiesMap[this.get('getDbTypeFromRadioValue')],
      serviceName = this.get('serviceConfig.serviceName');
    return dbProperties[serviceName] && dbProperties[serviceName][propertyType]
      ? dbProperties[serviceName][propertyType] : dbProperties[propertyType];
  },

  /**
   *
   * @param propertyType
   * @returns {*|Object}
   */
  getPropertyByType: function(propertyType) {
    if (dbInfo.dpPropertiesByServiceMap[this.get('serviceConfig.serviceName')]) {
      //@TODO: dbInfo.dpPropertiesByServiceMap has corresponding property name but does not have filenames with it. this can cause issue when there are multiple db properties with same name belonging to different files
      /** check if selected service has db properties**/
      return this.get('controller.selectedService.configs').findProperty('name', dbInfo.dpPropertiesByServiceMap[this.get('serviceConfig.serviceName')][propertyType]);
    }
    return null;
  },

  /**
   * This method hides properties <code>user_name<code> and <code>password<code> in case selected db is
   * "Existing MSSQL Server database with integrated authentication" or similar
   * @method handleSpecialUserPassProperties
   */
  handleSpecialUserPassProperties: function() {
    ['user_name', 'password'].forEach(function(pType) {
      var property = this.getPropertyByType(pType);
      if (property) {
        property.setProperties({
          'isVisible': !this.get('inMSSQLWithIA'),
          'isRequired': !this.get('inMSSQLWithIA')
        });
      }
    }, this);
  },

  /**
   * `Observer` that add <code>additionalView</code> to <code>App.ServiceConfigProperty</code>
   * that responsible for (if existing db selected)
   * 1. checking database connection
   * 2. showing jdbc driver setup warning msg.
   *
   * @method handleDBConnectionProperty
   **/
  handleDBConnectionProperty: function() {
    if (this.get('dontUseHandleDbConnection').contains(this.get('serviceConfig.name'))) {
      return;
    }
    var handledProperties = ['oozie_database', 'hive_database', 'DB_FLAVOR'];
    var currentValue = this.get('serviceConfig.value');
    /** TODO: Remove SQLA from the list of databases once Ranger DB_FLAVOR=SQLA is replaced with SQL Anywhere */
    var databases = /MySQL|PostgreSQL|Postgres|Oracle|Derby|MSSQL|SQLA|Anywhere/gi;
    var currentDB = currentValue.match(databases)[0];
    /** TODO: Remove SQLA from the list of databases once Ranger DB_FLAVOR=SQLA is replaced with SQL Anywhere */
    var checkDatabase = /existing/gi.test(currentValue);
    // db connection check button show up if existed db selected
    var propertyAppendTo1 = this.get('categoryConfigsAll').findProperty('displayName', 'Database URL');
    // warning msg under database type radio buttons, to warn the user to setup jdbc driver if existed db selected
    var propertyHive = this.get('categoryConfigsAll').findProperty('displayName', 'Hive Database');
    var propertyOozie = this.get('categoryConfigsAll').findProperty('displayName', 'Oozie Database');
    var propertyAppendTo2 = propertyHive ? propertyHive : propertyOozie;
    // RANGER specific
    if (this.get('serviceConfig.serviceName') === 'RANGER') {
      propertyAppendTo1 = this.get('categoryConfigsAll').findProperty('name', 'ranger.jpa.jdbc.url');
      propertyAppendTo2 = this.get('categoryConfigsAll').findProperty('name', 'DB_FLAVOR');
      // check for all db types when installing Ranger - not only for existing ones
      checkDatabase = true;
    }
    // Hive specific
    if (this.get('serviceConfig.serviceName') === 'HIVE') {
      // check for all db types when installing Hive - not only for existing ones
      checkDatabase = true;
    }
    if (propertyAppendTo1) {
      propertyAppendTo1.set('additionalView', null);
    }
    if (propertyAppendTo2) {
      propertyAppendTo2.set('additionalView', null);
    }
    var shouldAdditionalViewsBeSet = currentDB && checkDatabase && handledProperties.contains(this.get('serviceConfig.name')),
      driver = this.getDefaultPropertyValue('sql_jar_connector') ? this.getDefaultPropertyValue('sql_jar_connector').split("/").pop() : 'driver.jar',
      dbType = this.getDefaultPropertyValue('db_type'),
      dbName = this.getDefaultPropertyValue('db_name'),
      driverName = this.getDefaultPropertyValue('driver_name'),
      driverDownloadUrl = this.getDefaultPropertyValue('driver_download_url'),
      additionalView1 = shouldAdditionalViewsBeSet && !this.get('isNewDb') ? App.CheckDBConnectionView.extend({databaseName: dbType}) : null,
      additionalView2 = shouldAdditionalViewsBeSet ? Ember.View.extend({
        template: Ember.Handlebars.compile('<div class="alert alert-warning">{{{view.message}}}</div>'),
        message: function() {
          return Em.I18n.t('services.service.config.database.msg.jdbcSetup.detailed').format(dbName, dbType, driver, driverDownloadUrl, driverName);
        }.property()
      }) : null;
    if (propertyAppendTo1) {
      Em.run.next(function () {
        propertyAppendTo1.set('additionalView', additionalView1);
      });
    }
    if (propertyAppendTo2) {
      Em.run.next(function () {
        propertyAppendTo2.set('additionalView', additionalView2);
      });
    }
  }.observes('serviceConfig.value'),

  options: function () {
    return this.get('serviceConfig.options').map(function (option) {
      var dbTypePattern = /mysql|postgres|oracle|derby|mssql|sql\s?a/i,
        className = '',
        displayName = Em.get(option, 'displayName'),
        dbTypeMatch = displayName.match(dbTypePattern);
      if (dbTypeMatch) {
        var dbSourcePattern = /new/i,
          newDbMatch = displayName.match(dbSourcePattern);
        if (newDbMatch) {
          className += 'new-';
        }
        className += dbTypeMatch[0].replace(' ', '').toLowerCase();
      }
      return className ? Em.Object.create(option, {
        className: className,
        radioId: ''
      }) : option;
    });
  }.property('serviceConfig.options')
});

App.ServiceConfigRadioButton = Ember.Checkbox.extend(App.SupportsDependentConfigs, {
  tagName: 'input',
  attributeBindings: ['type', 'name', 'value', 'checked', 'disabled'],
  checked: false,
  clicked: false,
  type: 'radio',
  name: null,
  value: null,
  /**
   * Element id passed to label's <code>for</code> attribute.
   * @type {String}
   */
  radioId: '',

  didInsertElement: function () {
    this.set('radioId', this.get('elementId'));
    this.set('checked', this.get('parentView.serviceConfig.value') === this.get('value'));
  },

  click: function () {
    this.set('clicked', true);
    this.set('checked', true);
    this.onChecked();
  },

  onChecked: function () {
    // Wrapping the call with Ember.run.next prevents a problem where setting isVisible on component
    // causes JS error due to re-rendering.  For example, this occurs when switching the Config Group
    // in Service Config page
    if (this.get('clicked')) {
      Em.run.next(this, function() {
        this.set('parentView.serviceConfig.value', this.get('value'));
        this.sendRequestRorDependentConfigs(this.get('parentView.serviceConfig'));
        this.set('clicked', false);
        this.updateForeignKeys();
      });
    }
  }.observes('checked'),

  updateCheck: function() {
    if (!this.get('clicked')) {
      this.set('checked', this.get('parentView.serviceConfig.value') === this.get('value'));
      this.updateForeignKeys();
    }
  }.observes('parentView.serviceConfig.value'),

  updateForeignKeys: function() {
    var components = this.get('parentView.serviceConfig.options');
    if (components && components.someProperty('foreignKeys')) {
      this.get('controller.stepConfigs').findProperty('serviceName', this.get('parentView.serviceConfig.serviceName')).propertyDidChange('errorCount');
    }
  },


  disabled: function () {
    return !this.get('parentView.serviceConfig.isEditable') ||
      !['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name')) && /^New\s\w+\sDatabase$/.test(this.get('value'));
  }.property('parentView.serviceConfig.isEditable')
});

App.ServiceConfigComboBox = Ember.Select.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.SupportsDependentConfigs, {
  contentBinding: 'serviceConfig.options',
  selectionBinding: 'serviceConfig.value',
  placeholderBinding: 'serviceConfig.savedValue',
  classNames: [ 'col-md-3' ]
});


/**
 * Base component for host config with popover support
 */
App.ServiceConfigHostPopoverSupport = Ember.Mixin.create({

  /**
   * Config object. It will instance of App.ServiceConfigProperty
   */
  serviceConfig: null,

  didInsertElement: function () {
    App.popover(this.$(), {
      title: this.get('serviceConfig.displayName'),
      content: this.get('serviceConfig.description'),
      placement: 'right',
      trigger: 'hover'
    });
  }
});

/**
 * Master host component.
 * Show hostname without ability to edit it
 * @type {*}
 */
App.ServiceConfigMasterHostView = Ember.View.extend(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {

  classNames: ['master-host', 'col-md-6'],
  valueBinding: 'serviceConfig.value',

  template: Ember.Handlebars.compile('{{view.value}}')

});

/**
 * text field property view that enables possibility
 * for check connection
 * @type {*}
 */
App.checkConnectionView = App.ServiceConfigTextField.extend({
  didInsertElement: function() {
    this._super();
    if (this.get('controller.isHostsConfigsPage')) {
      return;
    }
    var kdc = this.get('categoryConfigsAll').findProperty('name', 'kdc_type');
    var propertyAppendTo = this.get('categoryConfigsAll').findProperty('name', 'domains');
    if (propertyAppendTo) {
      try {
        propertyAppendTo.set('additionalView', App.CheckDBConnectionView.extend({databaseName: kdc && kdc.get('value')}));
      } catch (e) {
        console.error('error while adding "Test connection button"');
      }
    }
  }
});

/**
 * Show value as plain label in italics
 * @type {*}
 */
App.ServiceConfigLabelView = Ember.View.extend(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {

  classNames: ['master-host', 'col-md-6'],
  valueBinding: 'serviceConfig.value',
  unitBinding: 'serviceConfig.unit',

  fullValue: function () {
    var value = this.get('value');
    var unit = this.get('unit');
    return unit ? value + ' ' + unit : value;
  }.property('value', 'unit'),

  template: Ember.Handlebars.compile('<i>{{formatWordBreak view.fullValue}}</i>')
});

/**
 * Base component to display Multiple hosts
 * @type {*}
 */
App.ServiceConfigMultipleHostsDisplay = Ember.Mixin.create(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {

  hasNoHosts: function () {
    if (!this.get('value')) {
      return true;
    }
    return !this.get('value.length');
  }.property('value'),

  formatValue: Em.computed.ifThenElseByKeys('hasOneHost', 'value.firstObject', 'value'),

  hasOneHost: Em.computed.equal('value.length', 1),

  hasMultipleHosts: Em.computed.gt('value.length', 1),

  otherLength: function () {
    var len = this.get('value.length');
    if (len > 2) {
      return Em.I18n.t('installer.controls.serviceConfigMultipleHosts.others').format(len - 1);
    }
    return Em.I18n.t('installer.controls.serviceConfigMultipleHosts.other');
  }.property('value')

});

/**
 * Multiple Slave Hosts component
 * @type {*}
 */
App.ServiceConfigComponentHostsView = Ember.View.extend(App.ServiceConfigMultipleHostsDisplay, App.ServiceConfigCalculateId, {

  viewName: 'serviceConfigSlaveHostsView',

  classNames: ['component-hosts', 'form-text'],

  valueBinding: 'serviceConfig.value',

  templateName: require('templates/wizard/component_hosts'),

  firstHost: Em.computed.firstNotBlank('value.firstObject', 'serviceConfig.value.firstObject'),

  /**
   * Onclick handler for link
   */
  showHosts: function () {
    var serviceConfig = this.get('serviceConfig');
    App.ModalPopup.show({
      header: Em.I18n.t('installer.controls.serviceConfigMasterHosts.header').format(serviceConfig.category),
      bodyClass: Ember.View.extend({
        serviceConfig: serviceConfig,
        templateName: require('templates/wizard/component_hosts_popup')
      }),
      secondary: null
    });
  }

});


/**
 * DropDown component for <code>select hosts for groups</code> popup
 * @type {*}
 */
App.SlaveComponentDropDownGroupView = Ember.View.extend(App.ServiceConfigCalculateId, {

  viewName: "slaveComponentDropDownGroupView",

  /**
   * On change handler for <code>select hosts for groups</code> popup
   * @param event
   */
  changeGroup: function (event) {
    var host = this.get('content');
    var groupName = $('#' + this.get('elementId') + ' select').val();
    this.get('controller').changeHostGroup(host, groupName);
  },

  optionTag: Ember.View.extend({

    /**
     * Whether current value(OptionTag value) equals to host value(assigned to SlaveComponentDropDownGroupView.content)
     */
    selected: function () {
      return this.get('parentView.content.group') === this.get('content');
    }.property('content')
  })
});

/**
 * View for testing connection to database.
 **/
App.CheckDBConnectionView = Ember.View.extend({
  templateName: require('templates/common/form/check_db_connection'),
  /** @property {string} btnCaption - text for button **/
  btnCaption: function() {
    return this.get('parentView.service.serviceName') === 'KERBEROS'
      ? Em.I18n.t('services.service.config.kdc.btn.idle')
      : Em.I18n.t('services.service.config.database.btn.idle')
  }.property('parentView.service.serviceName'),
  /** @property {string} responseCaption - text for status link **/
  responseCaption: null,
  /** @property {boolean} isConnecting - is request to server activated **/
  isConnecting: false,
  /** @property {boolean} isValidationPassed - check validation for required fields **/
  isValidationPassed: null,
  /** @property {string} databaseName- name of current database **/
  databaseName: null,
  /** @property {boolean} isRequestResolved - check for finished request to server **/
  isRequestResolved: false,
  /** @property {boolean} isConnectionSuccess - check for successful connection to database **/
  isConnectionSuccess: null,
  /** @property {string} responseFromServer - message from server response **/
  responseFromServer: null,
  /** @property {Object} ambariRequiredProperties - properties that need for custom action request **/
  ambariRequiredProperties: null,
  /** @property {Number} currentRequestId - current custom action request id **/
  currentRequestId: null,
  /** @property {Number} currentTaskId - current custom action task id **/
  currentTaskId: null,
  /** @property {jQuery.Deferred} request - current $.ajax request **/
  request: null,
  /** @property {Number} pollInterval - timeout interval for ajax polling **/
  pollInterval: 3000,
  /** @property {Object} logsPopup - popup with DB connection check info **/
  logsPopup: null,
  /** @property {string} hostNameProperty - host name property based on service and database names **/
  hostNameProperty: function() {
    if (!/wizard/i.test(this.get('controller.name')) && this.get('parentView.service.serviceName') === 'HIVE') {
      return this.get('parentView.service.serviceName').toLowerCase() + '_hostname';
    } else if (this.get('parentView.service.serviceName') === 'KERBEROS') {
      return 'kdc_hosts';
    } else if (this.get('parentView.service.serviceName') === 'RANGER') {
      return '{0}_{1}_host'.format(this.get('parentView.service.serviceName').toLowerCase(), this.get('databaseName').toLowerCase());
    }
    return '{0}_existing_{1}_host'.format(this.get('parentView.service.serviceName').toLowerCase(), this.get('databaseName').toLowerCase());
  }.property('databaseName'),
  /** @property {boolean} isBtnDisabled - disable button on failed validation or active request **/
  isBtnDisabled: Em.computed.or('!isValidationPassed', 'isConnecting'),
  /** @property {object} requiredProperties - properties that necessary for database connection **/
  requiredProperties: function() {
    var ranger = App.StackService.find().findProperty('serviceName', 'RANGER');
    var propertiesMap = {
      OOZIE: ['oozie.db.schema.name', 'oozie.service.JPAService.jdbc.username', 'oozie.service.JPAService.jdbc.password', 'oozie.service.JPAService.jdbc.driver', 'oozie.service.JPAService.jdbc.url'],
      HIVE: ['ambari.hive.db.schema.name', 'javax.jdo.option.ConnectionUserName', 'javax.jdo.option.ConnectionPassword', 'javax.jdo.option.ConnectionDriverName', 'javax.jdo.option.ConnectionURL'],
      KERBEROS: ['kdc_hosts'],
      RANGER: ranger && App.StackService.find().findProperty('serviceName', 'RANGER').compareCurrentVersion('0.5') > -1 ?
          ['db_user', 'db_password', 'db_name', 'ranger.jpa.jdbc.url', 'ranger.jpa.jdbc.driver'] :
          ['db_user', 'db_password', 'db_name', 'ranger_jdbc_connection_url', 'ranger_jdbc_driver']
    };
    return propertiesMap[this.get('parentView.service.serviceName')];
  }.property(),
  /** @property {Object} propertiesPattern - check pattern according to type of connection properties **/
  propertiesPattern: function() {
    var patterns = {
      db_connection_url: /jdbc\.url|connection_url|connectionurl|kdc_hosts/ig
    };
    if (this.get('parentView.service.serviceName') != "KERBEROS") {
      patterns.user_name = /(username|dblogin|db_user)$/ig;
      patterns.user_passwd = /(dbpassword|password|db_password)$/ig;
    }
    return patterns;
  }.property('parentView.service.serviceName'),
  /** @property {String} masterHostName - host name location of Master Component related to Service **/
  masterHostName: function() {
    var serviceMasterMap = {
      'OOZIE': 'oozie_server_hosts',
      'HDFS': 'hadoop_host',
      'HIVE': 'hive_metastore_hosts',
      'KERBEROS': 'kdc_hosts',
      'RANGER': 'ranger_server_hosts'
    };
    return this.get('parentView.categoryConfigsAll').findProperty('name', serviceMasterMap[this.get('parentView.service.serviceName')]).get('value');
  }.property('parentView.service.serviceName', 'parentView.categoryConfigsAll.@each.value'),
  /** @property {Object} connectionProperties - service specific config values mapped for custom action request **/
  connectionProperties: function() {
    var propObj = {};
    for (var key in this.get('propertiesPattern')) {
      propObj[key] = this.getConnectionProperty(this.get('propertiesPattern')[key]);
    }

    if (this.get('parentView.service.serviceName') === 'RANGER') {
      var dbFlavor = this.get('parentView.categoryConfigsAll').findProperty('name','DB_FLAVOR').get('value'),
        /** TODO: Remove SQLA from the list of databases once Ranger DB_FLAVOR=SQLA is replaced with SQL Anywhere */
        databasesTypes = /MYSQL|POSTGRES|ORACLE|MSSQL|SQLA|Anywhere/gi,
        dbType = dbFlavor.match(databasesTypes)?dbFlavor.match(databasesTypes)[0].toLowerCase():'';

      if (dbType==='oracle') {
        // fixes oracle SYSDBA issue
        propObj['user_name'] = "\'%@ as sysdba\'".fmt(propObj['user_name']);
      }
    }
    return propObj;
  }.property('parentView.categoryConfigsAll.@each.value'),
  /**
   * Properties that stores in local storage used for handling
   * last success connection.
   *
   * @property {Object} preparedDBProperties
   **/
  preparedDBProperties: function() {
    var propObj = {};
    for (var key in this.get('propertiesPattern')) {
      var propName = this.getConnectionProperty(this.get('propertiesPattern')[key], true);
      propObj[propName] = this.get('parentView.categoryConfigsAll').findProperty('name', propName).get('value');
    }
    return propObj;
  }.property(),
  /** Check validation and load ambari properties **/
  didInsertElement: function() {
    var kdc = this.get('parentView.categoryConfigsAll').findProperty('name', 'kdc_type');
    if (kdc) {
      var name = kdc.get('value');
      if (name == 'Existing MIT KDC') {
        name = 'KDC';
      } else if (name == 'Existing IPA') {
        name = 'IPA';
      } else {
        name = 'AD';
      }
      App.popover(this.$('.connection-result'), {
        title: Em.I18n.t('services.service.config.database.btn.idle'),
        content: Em.I18n.t('installer.controls.checkConnection.popover').format(name),
        placement: 'right',
        trigger: 'hover'
      });
    }
    this.handlePropertiesValidation();
    this.getAmbariProperties();
  },
  /** On view destroy **/
  willDestroyElement: function() {
    this.set('isConnecting', false);
    this._super();
  },
  /**
   * Observer that take care about enabling/disabling button based on required properties validation.
   *
   * @method handlePropertiesValidation
   **/
  handlePropertiesValidation: function() {
    this.restore();
    var isValid = true;
    var properties = [].concat(this.get('requiredProperties'));
    properties.push(this.get('hostNameProperty'));
    properties.forEach(function(propertyName) {
      var property = this.get('parentView.categoryConfigsAll').findProperty('name', propertyName);
      if(property && !property.get('isValid')) isValid = false;
    }, this);
    this.set('isValidationPassed', isValid);
  }.observes('parentView.categoryConfigsAll.@each.isValid', 'parentView.categoryConfigsAll.@each.value', 'databaseName'),

  getConnectionProperty: function (regexp, isGetName) {
    var _this = this;
    var propertyName = _this.get('requiredProperties').filter(function (item) {
      return regexp.test(item);
    })[0];
    return (isGetName) ? propertyName : _this.get('parentView.categoryConfigsAll').findProperty('name', propertyName).get('value');
  },
  /**
   * Set up ambari properties required for custom action request
   *
   * @method getAmbariProperties
   **/
  getAmbariProperties: function() {
    var clusterController = App.router.get('clusterController');
    var _this = this;
    if (!App.isEmptyObject(App.db.get('tmp', 'ambariProperties')) && !this.get('ambariProperties')) {
      this.set('ambariProperties', App.db.get('tmp', 'ambariProperties'));
      return;
    }
    if (App.isEmptyObject(clusterController.get('ambariProperties'))) {
      clusterController.loadAmbariProperties().done(function(data) {
        _this.formatAmbariProperties(data.RootServiceComponents.properties);
      });
    } else {
      this.formatAmbariProperties(clusterController.get('ambariProperties'));
    }
  },

  formatAmbariProperties: function(properties) {
    var defaults = {
      threshold: "60",
      ambari_server_host: location.hostname,
      check_execute_list : "db_connection_check"
    };
    var properties = App.permit(properties, ['jdk.name','jdk_location','java.home']);
    var renameKey = function(oldKey, newKey) {
      if (properties[oldKey]) {
        defaults[newKey] = properties[oldKey];
        delete properties[oldKey];
      }
    };
    renameKey('java.home', 'java_home');
    renameKey('jdk.name', 'jdk_name');
    $.extend(properties, defaults);
    App.db.set('tmp', 'ambariProperties', properties);
    this.set('ambariProperties', properties);
  },
  /**
   * `Action` method for starting connect to current database.
   *
   * @method connectToDatabase
   **/
  connectToDatabase: function() {
    if (this.get('isBtnDisabled')) return;
    this.set('isRequestResolved', false);
    App.db.set('tmp', this.get('parentView.service.serviceName') + '_connection', {});
    this.setConnectingStatus(true);
    if (App.get('testMode')) {
      this.startPolling();
    } else {
      this.runCheckConnection();
    }
  },

  /**
   * runs check connections methods depending on service
   * @return {void}
   * @method runCheckConnection
   */
  runCheckConnection: function() {
    if (this.get('parentView.service.serviceName') === 'KERBEROS') {
      this.runKDCCheck();
    } else {
      this.createCustomAction();
    }
  },

  /**
   * send ajax request to perforn kdc host check
   * @return {App.ajax}
   * @method runKDCCheck
   */
  runKDCCheck: function() {
    return App.ajax.send({
      name: 'admin.kerberos_security.test_connection',
      sender: this,
      data: {
        kdcHostname: this.get('masterHostName')
      },
      success: 'onRunKDCCheckSuccess',
      error: 'onCreateActionError'
    });
  },

  /**
   *
   * @param data
   */
  onRunKDCCheckSuccess: function(data) {
    var statusCode = {
      success: 'REACHABLE',
      failed: 'UNREACHABLE'
    };
    if (data == statusCode['success']) {
      this.setResponseStatus('success');
    } else {
      this.setResponseStatus('failed');
    }
    this.set('responseFromServer', data);
  },

  /**
   * Run custom action for database connection.
   *
   * @method createCustomAction
   **/
  createCustomAction: function() {
    var isServiceInstalled = App.Service.find(this.get('parentView.service.serviceName')).get('isLoaded');
    var params = $.extend(true, {}, { db_name: this.get('databaseName').toLowerCase() }, this.get('connectionProperties'), this.get('ambariProperties'));
    App.ajax.send({
      name: (isServiceInstalled) ? 'cluster.custom_action.create' : 'custom_action.create',
      sender: this,
      data: {
        requestInfo: {
          parameters: params
        },
        filteredHosts: [this.get('masterHostName')]
      },
      success: 'onCreateActionSuccess',
      error: 'onCreateActionError'
    });
  },
  /**
   * Run updater if task is created successfully.
   *
   * @method onConnectActionS
   **/
  onCreateActionSuccess: function(data) {
    this.set('currentRequestId', data.Requests.id);
    App.ajax.send({
      name: 'custom_action.request',
      sender: this,
      data: {
        requestId: this.get('currentRequestId')
      },
      success: 'setCurrentTaskId'
    });
  },

  setCurrentTaskId: function(data) {
    this.set('currentTaskId', data.items[0].Tasks.id);
    this.startPolling();
  },

  startPolling: function() {
    if (this.get('isConnecting'))
      this.getTaskInfo();
  },

  getTaskInfo: function() {
    var request = App.ajax.send({
      name: 'custom_action.request',
      sender: this,
      data: {
        requestId: this.get('currentRequestId'),
        taskId: this.get('currentTaskId')
      },
      success: 'getTaskInfoSuccess'
    });
    this.set('request', request);
  },

  getTaskInfoSuccess: function(data) {
    var task = data.Tasks;
    this.set('responseFromServer', {
      stderr: task.stderr,
      stdout: task.stdout
    });
    if (task.status === 'COMPLETED') {
      var structuredOut = task.structured_out.db_connection_check;
      if (structuredOut.exit_code != 0) {
        this.set('responseFromServer', {
          stderr: task.stderr,
          stdout: task.stdout,
          structuredOut: structuredOut.message
        });
        this.setResponseStatus('failed');
      } else {
        App.db.set('tmp', this.get('parentView.service.serviceName') + '_connection', this.get('preparedDBProperties'));
        this.setResponseStatus('success');
      }
    }
    if (task.status === 'FAILED') {
      this.setResponseStatus('failed');
    }
    if (/PENDING|QUEUED|IN_PROGRESS/.test(task.status)) {
      Em.run.later(this, function() {
        this.startPolling();
      }, this.get('pollInterval'));
    }
  },

  onCreateActionError: function(jqXhr, status, errorMessage) {
    this.setResponseStatus('failed');
    this.set('responseFromServer', errorMessage);
  },

  setResponseStatus: function(isSuccess) {
    var isSuccess = isSuccess == 'success';
    this.setConnectingStatus(false);
    this.set('responseCaption', isSuccess ? Em.I18n.t('services.service.config.database.connection.success') : Em.I18n.t('services.service.config.database.connection.failed'));
    this.set('isConnectionSuccess', isSuccess);
    this.set('isRequestResolved', true);
    if (this.get('logsPopup')) {
      var statusString = isSuccess ? 'common.success' : 'common.error';
      this.set('logsPopup.header', Em.I18n.t('services.service.config.connection.logsPopup.header').format(this.get('databaseName'), Em.I18n.t(statusString)));
    }
  },
  /**
   * Switch captions and statuses for active/non-active request.
   *
   * @method setConnectionStatus
   * @param {Boolean} [active]
   */
  setConnectingStatus: function(active) {
    if (active) {
      this.set('responseCaption', Em.I18n.t('services.service.config.database.connection.inProgress'));
    }
    this.set('controller.testConnectionInProgress', !!active);
    this.set('btnCaption', !!active ? Em.I18n.t('services.service.config.database.btn.connecting') : Em.I18n.t('services.service.config.database.btn.idle'));
    this.set('isConnecting', !!active);
  },
  /**
   * Set view to init status.
   *
   * @method restore
   **/
  restore: function() {
    if (this.get('request')) {
      this.get('request').abort();
      this.set('request', null);
    }
    this.set('responseCaption', null);
    this.set('responseFromServer', null);
    this.setConnectingStatus(false);
    this.set('isRequestResolved', false);
  },
  /**
   * `Action` method for showing response from server in popup.
   *
   * @method showLogsPopup
   **/
  showLogsPopup: function() {
    if (this.get('isConnectionSuccess')) return;
    var _this = this;
    var statusString = this.get('isRequestResolved') ? 'common.error' : 'common.testing';
    var popup = App.showAlertPopup(Em.I18n.t('services.service.config.connection.logsPopup.header').format(this.get('databaseName'), Em.I18n.t(statusString)), null, function () {
      _this.set('logsPopup', null);
    });
    popup.reopen({
      onClose: function () {
        this._super();
        _this.set('logsPopup', null);
      }
    });
    if (typeof this.get('responseFromServer') == 'object') {
      popup.set('bodyClass', Em.View.extend({
        checkDBConnectionView: _this,
        templateName: require('templates/common/error_log_body'),
        openedTask: function () {
          return this.get('checkDBConnectionView.responseFromServer');
        }.property('checkDBConnectionView.responseFromServer.stderr', 'checkDBConnectionView.responseFromServer.stdout', 'checkDBConnectionView.responseFromServer.structuredOut')
      }));
    } else {
      popup.set('body', this.get('responseFromServer'));
    }
    this.set('logsPopup', popup);
    return popup;
  }
});

/**
 * View for switch group text
 *
 * @type {Em.View}
 */
App.SwitchToGroupView = Em.View.extend({

  group: null,

  tagName: 'a',

  classNames: ['action'],

  template: Ember.Handlebars.compile('{{ view.group.switchGroupTextShort }}'),

  didInsertElement: function() {
    var self = this;
    App.tooltip($(self.get('element')), {
      placement: 'top',
      title: self.get('group.switchGroupTextFull')
    });
  },

  willDestroyElement: function() {
    $(this.get('element')).tooltip('destroy');
  },

  click: function() {
    this.get('controller').selectConfigGroup({context: this.get('group')});
  }
});

/**
 * View with input field used to repo-version URLs
 * @type {*}
 */
App.BaseUrlTextField = Ember.TextField.extend({

  layout: Ember.Handlebars.compile('<div class="pull-left">{{yield}}</div> {{#if view.valueWasChanged}}<div class="pull-right"><a class="btn-sm" {{action "restoreValue" target="view"}}><i class="icon-undo"></i></a></div>{{/if}}'),

  /**
   * Binding in the template
   * @type {App.RepositoryVersion}
   */
  repository: null,

  /**
   * @type {string}
   */
  valueBinding: 'repository.baseUrl',

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

  /**
   *  validate base URL
   */
  validate: function () {
    if (this.get('repository.skipValidation')) {
      this.set('repository.hasError', false);
    } else {
      this.set('repository.hasError', !(validator.isValidBaseUrl(this.get('value'))));
    }
    this.get('parentView').uiValidation();
  }.observes('value', 'repository.skipValidation'),

  /**
   * Determines if user have put some new value
   * @type {boolean}
   */
  valueWasChanged: function () {
    return this.get('value') !== this.get('defaultValue');
  }.property('value', 'defaultValue'),

  didInsertElement: function () {
    this.set('defaultValue', this.get('value'));
  },

  /**
   * Restore value and unset error-flag
   * @method restoreValue
   */
  restoreValue: function () {
    this.set('value', this.get('defaultValue'));
  }
});
