/**
 * 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 stringUtils = require('utils/string_utils');

App.QuickViewLinks = Em.View.extend({

  isLoaded: false,

  loadTags: function () {
    App.ajax.send({
      name: 'config.tags',
      sender: this,
      success: 'loadTagsSuccess',
      error: 'loadTagsError'
    });
  },

  loadTagsSuccess: function (data) {
    this.get('actualTags').clear();
    var tags = [];
    var self = this;
    for (var prop in data.Clusters.desired_configs) {
      tags.push(Em.Object.create({
        siteName: prop,
        tagName: data.Clusters.desired_configs[prop]['tag']
      }));
    }
    this.get('actualTags').pushObjects(tags);
    this.setConfigProperties().done(function (data) {
      self.get('configProperties').pushObjects(data);
      self.getQuickLinksHosts();
    });
  },

  loadTagsError: function() {
    this.getQuickLinksHosts();
  },

  getQuickLinksHosts: function () {
    var masterHosts = App.HostComponent.find().filterProperty('isMaster').mapProperty('hostName').uniq();

    App.ajax.send({
      name: 'hosts.for_quick_links',
      sender: this,
      data: {
        clusterName: App.get('clusterName'),
        masterHosts: masterHosts.join(','),
        urlParams: ',host_components/metrics/hbase/master/IsActiveMaster'
      },
      success: 'setQuickLinksSuccessCallback'
    });
  },

  actualTags: [],

  configProperties: [],

  /**
   * list of files that contains properties for enabling/disabling ssl
   */
  requiredSiteNames: ['hadoop-env','yarn-env','hbase-env','oozie-env','mapred-env','storm-env', 'falcon-env', 'core-site', 'hdfs-site', 'hbase-site', 'oozie-site', 'yarn-site', 'mapred-site', 'storm-site', 'spark-defaults'],
  /**
   * Get public host name by its host name.
   *
   * @method getPublicHostName
   * @param {Object[]} hosts - list of hosts from response
   * @param {String} hostName
   * @return {String}
   **/
  getPublicHostName: function(hosts, hostName) {
    return Em.get(hosts.findProperty('Hosts.host_name', hostName), 'Hosts.public_host_name');
  },

  setConfigProperties: function () {
    this.get('configProperties').clear();
    var requiredSiteNames = this.get('requiredSiteNames');
    var tags = this.get('actualTags').filter(function (tag) {
      return requiredSiteNames.contains(tag.siteName);
    });
    return App.router.get('configurationController').getConfigsByTags(tags);
  },

  ambariProperties: function () {
    return App.router.get('clusterController.ambariProperties');
  },
  /**
   * Updated quick links. Here we put correct hostname to url
   */
  quickLinks: [],

  didInsertElement: function () {
    this.setQuickLinks();
  },

  findComponentHost: function (components, componentName) {
    var component = components.find(function (item) {
      return item.host_components.someProperty('HostRoles.component_name', componentName);
    });
    return component && component.Hosts.public_host_name;
  },

  setQuickLinks: function () {
    this.loadTags();
  }.observes('App.currentStackVersionNumber', 'App.singleNodeInstall'),

  setQuickLinksSuccessCallback: function (response) {
    var self = this;
    var quickLinks = [];
    var hosts = this.setHost(response, this.get('content.serviceName'));
    if (!hosts || !this.get('content.quickLinks')) {
      quickLinks = [{
          label: this.t('quick.links.error.label'),
          url: 'javascript:alert("' + this.t('contact.administrator') + '");return false;'
      }];
      this.set('quickLinks', quickLinks);
      this.set('isLoaded', true);
    } else if (hosts.length == 1) {

      quickLinks = this.get('content.quickLinks').map(function (item) {
        var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties());
        if (item.get('template')) {
          var port = item.get('http_config') && self.setPort(item, protocol);
          item.set('url', item.get('template').fmt(protocol, hosts[0], port));
        }
        return item;
      });
      this.set('quickLinks', quickLinks);
      this.set('isLoaded', true);
    } else {
      // multiple hbase masters or HDFS HA enabled
      var quickLinksArray = [];
      hosts.forEach(function(host) {
        var quickLinks = [];
        self.get('content.quickLinks').forEach(function (item) {
          var newItem = {};
          var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties());
          if (item.get('template')) {
            var port = item.get('http_config') && self.setPort(item, protocol);
            if (item.get('service_id')==='OOZIE') {
              newItem.url = item.get('template').fmt(protocol, host.publicHostName, port, App.router.get('loginName'));
            } else {
              newItem.url = item.get('template').fmt(protocol, host.publicHostName, port);
            }
            newItem.label = item.get('label');
          }
          quickLinks.push(newItem);
        });
        if (host.status) {
          quickLinks.set('publicHostNameLabel', Em.I18n.t('quick.links.publicHostName').format(host.publicHostName, host.status));
        } else {
          quickLinks.set('publicHostNameLabel', host.publicHostName);
        }
        quickLinksArray.push(quickLinks);
      }, this);
      this.set('quickLinksArray', quickLinksArray);
      this.set('isLoaded', true);
    }
  },

  /**
   * sets public host names for required masters of current service
   * @param {String} serviceName - selected serviceName
   * @param {JSON} response
   * @returns {Array} containing hostName(s)
   * @method setHost
   */
  setHost: function(response, serviceName) {
    if (App.get('singleNodeInstall')) {
      return [App.get('singleNodeAlias')];
    }
    var hosts = [];
    switch (serviceName) {
      case 'OOZIE':
        // active OOZIE components
        var components = this.get('content.hostComponents').filterProperty('componentName','OOZIE_SERVER').filterProperty('workStatus', 'STARTED');
        if (components && components.length > 1) {
          components.forEach(function (component) {
            hosts.push({
              'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name,
              'status': Em.I18n.t('quick.links.label.active')
            });
          });
        } else if (components && components.length === 1) {
          hosts[0] = this.findComponentHost(response.items, 'OOZIE_SERVER');
        }
        break;
      case "HDFS":
        if (this.get('content.snameNode')) {
          // not HA
          hosts[0] = this.findComponentHost(response.items, 'NAMENODE');
        } else {
          // HA enabled, need both two namenodes hosts
          this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').forEach(function (component) {
            hosts.push({'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name});
          });
          // assign each namenode status label
          if (this.get('content.activeNameNode')) {
            hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.activeNameNode.hostName'))).status = Em.I18n.t('quick.links.label.active');
          }
          if (this.get('content.standbyNameNode')) {
            hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode.hostName'))).status = Em.I18n.t('quick.links.label.standby');
          }
          if (this.get('content.standbyNameNode2')) {
            hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode2.hostName'))).status = Em.I18n.t('quick.links.label.standby');
          }
        }
        break;
      case "HBASE":
        var masterComponents = response.items.filter(function (item) {
          return item.host_components.someProperty('HostRoles.component_name', 'HBASE_MASTER');
        });
        var activeMaster, standbyMasters, otherMasters;
        activeMaster = masterComponents.filter(function (item) {
          return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true');
        });
        standbyMasters = masterComponents.filter(function (item) {
          return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false');
        });
        otherMasters = masterComponents.filter(function (item) {
          return !(item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true') || item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false'));
        });
        if (masterComponents.length > 1) {
          // need all hbase_masters hosts in quick links
          if (activeMaster) {
            activeMaster.forEach(function (item) {
              hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.active')});
            });
          }
          if (standbyMasters) {
            standbyMasters.forEach(function (item) {
              hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.standby')});
            });
          }
          if (otherMasters) {
            otherMasters.forEach(function (item) {
              hosts.push({'publicHostName': item.Hosts.public_host_name});
            });
          }
        } else {
          hosts[0] = masterComponents[0].Hosts.public_host_name;
        }
        break;
      case "YARN":
        if (App.get('isRMHaEnabled')) {
          this.get('content.hostComponents').filterProperty('componentName', 'RESOURCEMANAGER').forEach(function (component) {
            var newHost = {'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name};
            var status = '';
            switch (component.get('haStatus')) {
              case 'ACTIVE':
                status = Em.I18n.t('quick.links.label.active');
                break;
              case 'STANDBY':
                status = Em.I18n.t('quick.links.label.standby');
                break;
            }
            if (status) {
              newHost.status = status;
            }
            hosts.push(newHost);
          }, this);
        } else {
          hosts[0] = this.findComponentHost(response.items, 'RESOURCEMANAGER');
        }
        break;
      case "STORM":
        hosts[0] = this.findComponentHost(response.items, "STORM_UI_SERVER");
        break;
      default:
        var service = App.StackService.find().findProperty('serviceName', serviceName);
        if (service && service.get('hasMaster')) {
          hosts[0] = this.findComponentHost(response.items, this.get('content.hostComponents') && this.get('content.hostComponents').findProperty('isMaster', true).get('componentName'));
        }
        break;
    }
    return hosts;
  },

  /**
   * services that supports security. this array is used to find out protocol.
   * becides GANGLIA, YARN, MAPREDUCE2. These properties use
   * their properties to know protocol
   */
  servicesSupportsHttps: ["HDFS", "HBASE"],

  /**
   * setProtocol - if cluster is secure for some services (GANGLIA, MAPREDUCE2, YARN and servicesSupportsHttps)
   * protocol becomes "https" otherwise "http" (by default)
   * @param {String} service_id - service name
   * @param {Object} configProperties
   * @param {Object} ambariProperties
   * @returns {string} "https" or "http" only!
   * @method setProtocol
   */
  setProtocol: function (service_id, configProperties, ambariProperties) {
    var hadoopSslEnabled = false;
    if (configProperties && configProperties.length > 0) {
      var hdfsSite = configProperties.findProperty('type', 'hdfs-site');
      hadoopSslEnabled = (hdfsSite && Em.get(hdfsSite, 'properties') && hdfsSite.properties['dfs.http.policy'] === 'HTTPS_ONLY');
    }
    switch (service_id) {
      case "GANGLIA":
        return (ambariProperties && ambariProperties['ganglia.https'] == "true") ? "https" : "http";
        break;
      case "YARN":
        var yarnProperties = configProperties && configProperties.findProperty('type', 'yarn-site');
        if (yarnProperties && yarnProperties.properties) {
          if (yarnProperties.properties['yarn.http.policy'] === 'HTTPS_ONLY') {
            return "https";
          } else if (yarnProperties.properties['yarn.http.policy'] === 'HTTP_ONLY') {
            return "http";
          }
        }
        return hadoopSslEnabled ? "https" : "http";
        break;
      case "MAPREDUCE2":
        var mapred2Properties = configProperties && configProperties.findProperty('type', 'mapred-site');
        if (mapred2Properties && mapred2Properties.properties) {
          if (mapred2Properties.properties['mapreduce.jobhistory.http.policy'] === 'HTTPS_ONLY') {
            return "https";
          } else if (mapred2Properties.properties['mapreduce.jobhistory.http.policy'] === 'HTTP_ONLY') {
            return "http";
          }
        }
        return hadoopSslEnabled ? "https" : "http";
        break;
      default:
        return this.get('servicesSupportsHttps').contains(service_id) && hadoopSslEnabled ? "https" : "http";
    }
  },

  /**
   * sets the port of quick link
   * @param item
   * @param protocol
   * @returns {*}
   * @method setPort
   */
  setPort: function (item, protocol) {
    var configProperties = this.get('configProperties');
    var config = item.get('http_config');
    var defaultPort = item.get('default_http_port');
    if (protocol === 'https' && item.get('https_config')) {
      config = item.get('https_config');
      if (item.get('default_https_port')) {
        defaultPort = item.get('default_https_port');
      }
    }
    var site = configProperties.findProperty('type', item.get('site'));
    var propertyValue = site && site.properties[config];
    if (!propertyValue) {
      return defaultPort;
    }

    var re = new RegExp(item.get('regex'));

    var portValue = propertyValue.match(re);
    return  portValue[1];
  },

  linkTarget: function () {
    switch (this.get('content.serviceName').toLowerCase()) {
      case "hdfs":
      case "yarn":
      case "mapreduce2":
      case "hbase":
      case "oozie":
      case "ganglia":
      case "storm":
      case "falcon":
        return "_blank";
        break;
      default:
        return "";
        break;
    }
  }.property('service')

});
