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

  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, {

  onValueUpdate: function () {
    if (!this.get('isVisible')) return;
    var self = this, config = this.get('serviceConfig'),
    controller = this.get('controller');
    delay(function(){
      self.sendRequestRorDependentConfigs(config, controller);
    }, 500);
  }.observes('serviceConfig.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({
  idClass: Ember.computed(function () {
    var config = this.get('config') && this.get('config.widget') ? this.get('config') : this.get('serviceConfig') || {};
    var label = Em.get(config, 'name') ? Em.get(config, 'name').toLowerCase().replace(/\./g, '-') : '',
        fileName = Em.get(config, 'filename') ? Em.get(config, 'filename').toLowerCase().replace(/\./g, '-') : '',
        group = Em.get(config, 'group.name') || 'default',
        isOrigin = Em.getWithDefault(config, 'compareConfigs.length', 0) > 0 ? '-origin' : '';
    return 'service-config-' + label + '-' + fileName + '-' + group + isOrigin;
  }),
  classNameBindings: 'idClass'
});

/**
 * Default input control
 * @type {*}
 */
App.ServiceConfigTextField = Ember.TextField.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.ValueObserver, {

  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-small'];
    } else if (this.get('serviceConfig.displayType') === 'principal') {
      return ['span12'];
    } else {
      return ['span9'];
    }
  }.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',
  classNames: 'display-inline-block',

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

  isUIDGIDVisible: function () {
    var overrideUid = this.get('parentView').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-append', 'with-unit'],
  placeholderBinding: 'serviceConfig.savedValue',

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

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

  serviceConfig: null,
  type: 'password',
  attributeBindings:['readOnly'],
  valueBinding: 'serviceConfig.value',
  classNames: [ 'span4' ],
  placeholder: Em.I18n.t('form.item.placeholders.typePassword'),

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

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

  retypePasswordView: Ember.TextField.extend({
    placeholder: Em.I18n.t('form.passwordRetype'),
    attributeBindings:['readOnly'],
    type: 'password',
    classNames: [ 'span4', 'retyped-password' ],
    keyPress: function (event) {
      if (event.keyCode == 13) {
        return false;
      }
    },
    valueBinding: 'parentView.serviceConfig.retypedPassword',
    readOnly: Em.computed.not('parentView.serviceConfig.isEditable')
  }),

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

});

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

  valueBinding: 'serviceConfig.value',
  rows: 4,
  classNames: ['directories'],
  classNameBindings: ['widthClass'],
  widthClass: 'span9'
});


/**
 * 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: ['span10']
});

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

/**
 * Checkbox control
 * @type {*}
 */
App.ServiceConfigCheckbox = 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.$().parent('.control-group').find('.bootstrap-checkbox');
  }.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');
    Object.keys(this.get('allowedPairs')).forEach(function(key) {
      if (this.get('allowedPairs')[key].contains(this.get('serviceConfig.value'))) {
        this.set('trueValue', this.get('allowedPairs')[key][0]);
        this.set('falseValue', 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.$().checkbox({
          defaultState: self.get('serviceConfig.value'),
          buttonStyle: 'btn-link btn-large',
          checkedClass: 'icon-check',
          uncheckedClass: 'icon-check-empty'
        });
        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'));
      // change bootstrap-checkbox state
      this.$().change();
    }
  },

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

  //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 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();
        this.handleDBConnectionProperty();
      } 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 databasesTypes = /MySQL|Postgres|Oracle|Derby|MSSQL|SQLA|Anywhere/gi;
    var currentDBType = currentValue.match(databasesTypes)[0];
    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">{{{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
      }) : 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,

  didInsertElement: function () {
    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: [ 'span3' ]
});


/**
 * 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', 'span6'],
  valueBinding: 'serviceConfig.value',

  template: Ember.Handlebars.compile('{{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', 'span6'],
  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 === 0;
  }.property('value'),

  formatValue: function() {
    if (Em.isArray(this.get('value')) && this.get('value').length === 1) {
      return this.get('value.firstObject');
    } else {
      return this.get('value');
    }
  }.property('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);
    } else {
      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', 'span6'],

  valueBinding: 'serviceConfig.value',

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

  /**
   * 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 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: App.get('isHadoop23Stack') ? ['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('App.isHadoop23Stack'),
  /** @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.$(), {
        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-small" {{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'));
  }
});
