text: import { next } from '@ember/runloop';
  import { inject as service } from '@ember/service';
  import { get, set, setProperties, observer } from '@ember/object';
  import Component from '@ember/component';
  import layout from './template';
  import $ from 'jquery';
  
  const KINDS = ['NodePort', 'HostPort', 'ClusterIP', 'LoadBalancer'];
  
  const protocolOptions = [
    {
      label: 'TCP',
      value: 'TCP'
    },
    {
      label: 'UDP',
      value: 'UDP'
    }
  ];
  
  export default Component.extend({
    intl:                service(),
    scope:               service(),
    settings:            service(),
    capabilities:        service(),
  
    layout,
    protocolOptions,
    initialPorts:        null,
    editing:             false,
    showWarning:         false,
    kindChoices:         null,
  
    ports:               null,
    nodePortFrom:        null,
    nodePortTo:          null,
    nodePortPlaceholder: null,
  
    init() {
      this._super(...arguments);
      this.initPorts();
      this.nodePortRangeDidChange();
      this.initKindChoices();
    },
  
    actions: {
      addPort() {
        this.get('ports').pushObject(get(this, 'store').createRecord({
          type:          'containerPort',
          kind:          'NodePort',
          protocol:      'TCP',
          containerPort: '',
        }));
  
        next(() => {
          if (this.isDestroyed || this.isDestroying) {
            return;
          }
  
          $('INPUT.public').last()[0].focus();
        });
      },
  
      removePort(obj) {
        this.get('ports').removeObject(obj);
      },
    },
  
    portsChanged: observer('ports.@each.{containerPort,dnsName,hostIp,kind,name,protocol,sourcePort,_ipPort}', function() {
      const errors = [];
      const intl = get(this, 'intl');
      const ports = get(this, 'ports');
  
      ports.forEach((obj) => {
        let containerPort = obj.containerPort;
  
        if ( !containerPort ) {
          errors.push(intl.t('formPorts.error.privateRequired'));
        }
  
        if (obj.kind === 'HostPort' && !get(obj, '_ipPort')) {
          errors.push(intl.t('formPorts.error.hostPort.sourcePortRequired'));
        }
  
        if (obj.kind === 'LoadBalancer' && !get(obj, 'sourcePort')) {
          errors.push(intl.t('formPorts.error.loadBalancer.sourcePortRequired'));
        }
  
        if ( !obj.sourcePort ) {
          delete obj['sourcePort'];
        }
  
        if ( get(obj, 'kind') === 'HostPort' ) {
          let port = get(obj, '_ipPort') || '';
          let ip;
          const idx = port.lastIndexOf(':');
  
          if ( idx >= 0 ) {
            ip = port.substr(0, idx);
            port = port.substr(idx + 1);
          }
  
          const toSet = {};
  
          if ( ip ) {
            if ( get(obj, 'hostIp') !== ip ) {
              toSet['hostIp'] = ip;
            }
          } else {
            delete obj['hostIp'];
          }
  
          port = parseInt(port, 10) || undefined;
          if ( port !== get(obj, 'sourcePort') ) {
            toSet['sourcePort'] = port;
          }
  
          setProperties(obj, toSet);
        }
      });
  
      this.set('errors', errors.uniq());
      if (this.changed) {
        this.changed(ports.slice());
      }
    }),
  
    nodePortRangeDidChange: observer('intl.locale', 'scope.currentCluster.rancherKubernetesEngineConfig.services.kubeApi.serviceNodePortRange', function() {
      const intl          = get(this, 'intl');
      const nodePortRange = get(this, 'scope.currentCluster.rancherKubernetesEngineConfig.services.kubeApi.serviceNodePortRange')
      const ccPorts       = get(this, 'capabilities.allowedNodePortRanges');
  
      if ( nodePortRange  ) {
        const ports = nodePortRange.split('-');
  
        if ( ports.length === 2 ) {
          let from = parseInt(ports[0], 10);
          let to   = parseInt(ports[1], 10);
  
          if (ccPorts.length > 0) {
            if (from < ccPorts[0]) {
              from = ccPorts[0];
            }
  
            if (to > ccPorts[1]) {
              to = ccPorts[1];
            }
          }
  
          setProperties(this, {
            nodePortFrom:        from,
            nodePortTo:          to,
            nodePortPlaceholder: intl.t('formPorts.nodePort.customPortRangePlaceholder', {
              range: nodePortRange,
              port:  from
            })
          });
  
          return;
        }
      }
  
      setProperties(this, {
        nodePortFrom:        1,
        nodePortTo:          65535,
        nodePortPlaceholder: intl.t('formPorts.nodePort.placeholder')
      });
    }),
  
    initPorts() {
      let ports = get(this, 'initialPorts') || [];
  
      ports.forEach((obj) => {
        if ( get(obj, 'kind') === 'HostPort' ) {
          const ip = get(obj, 'hostIp');
          const port = get(obj, 'sourcePort');
  
          set(obj, '_ipPort', (ip ? `${ ip  }:` : '') + port);
        }
      });
  
      set(this, 'ports', ports);
    },
  
    initKindChoices() {
      const loadBalancerCapabilites = get(this, 'capabilities.loadBalancerCapabilites');
  
      set(this, 'kindChoices', KINDS.map((k) => {
        let out = {
          translationKey: null,
          value:          k,
        };
  
        if (!loadBalancerCapabilites.l4LoadBalancerEnabled && k === 'LoadBalancer') {
          setProperties(out, {
            translationKey: `formPorts.kind.LoadBalancerDisbaled`,
            disabled:       true
          })
        } else {
          set(out, 'translationKey', `formPorts.kind.${ k }`);
        }
  
        return out;
      }));
    },
  
  });
  