text: angular.module('createContainer', [])
  .controller('CreateContainerController', ['$scope', '$state', '$stateParams', '$filter', 'Config', 'Info', 'Container', 'ContainerHelper', 'Image', 'ImageHelper', 'Volume', 'Network', 'Messages',
  function ($scope, $state, $stateParams, $filter, Config, Info, Container, ContainerHelper, Image, ImageHelper, Volume, Network, Messages) {
  
    $scope.formValues = {
      alwaysPull: true,
      Console: 'none',
      Volumes: [],
      Registry: '',
      NetworkContainer: '',
      Labels: []
    };
  
    $scope.imageConfig = {};
  
    $scope.config = {
      Image: '',
      Env: [],
      ExposedPorts: {},
      HostConfig: {
        RestartPolicy: {
          Name: 'no'
        },
        PortBindings: [],
        Binds: [],
        NetworkMode: 'bridge',
        Privileged: false
      },
      Labels: {}
    };
  
    $scope.addVolume = function() {
      $scope.formValues.Volumes.push({ name: '', containerPath: '' });
    };
  
    $scope.removeVolume = function(index) {
      $scope.formValues.Volumes.splice(index, 1);
    };
  
    $scope.addEnvironmentVariable = function() {
      $scope.config.Env.push({ name: '', value: ''});
    };
  
    $scope.removeEnvironmentVariable = function(index) {
      $scope.config.Env.splice(index, 1);
    };
  
    $scope.addPortBinding = function() {
      $scope.config.HostConfig.PortBindings.push({ hostPort: '', containerPort: '', protocol: 'tcp' });
    };
  
    $scope.removePortBinding = function(index) {
      $scope.config.HostConfig.PortBindings.splice(index, 1);
    };
  
    $scope.addLabel = function() {
      $scope.formValues.Labels.push({ name: '', value: ''});
    };
  
    $scope.removeLabel = function(index) {
      $scope.formValues.Labels.splice(index, 1);
    };
  
    Config.$promise.then(function (c) {
      var containersToHideLabels = c.hiddenLabels;
  
      Volume.query({}, function (d) {
        $scope.availableVolumes = d.Volumes;
      }, function (e) {
        Messages.error("Failure", e, "Unable to retrieve volumes");
      });
  
      Network.query({}, function (d) {
        var networks = d;
        if ($scope.endpointMode.provider === 'DOCKER_SWARM' || $scope.endpointMode.provider === 'DOCKER_SWARM_MODE') {
          networks = d.filter(function (network) {
            if (network.Scope === 'global') {
              return network;
            }
          });
          $scope.globalNetworkCount = networks.length;
          networks.push({Name: "bridge"});
          networks.push({Name: "host"});
          networks.push({Name: "none"});
        }
        networks.push({Name: "container"});
        $scope.availableNetworks = networks;
        if (!_.find(networks, {'Name': 'bridge'})) {
          $scope.config.HostConfig.NetworkMode = 'nat';
        }
      }, function (e) {
        Messages.error("Failure", e, "Unable to retrieve networks");
      });
  
      Container.query({}, function (d) {
        var containers = d;
        if (containersToHideLabels) {
          containers = ContainerHelper.hideContainers(d, containersToHideLabels);
        }
        $scope.runningContainers = containers;
      }, function(e) {
        Messages.error("Failure", e, "Unable to retrieve running containers");
      });
    });
  
    // TODO: centralize, already present in templatesController
    function createContainer(config) {
      Container.create(config, function (d) {
        if (d.message) {
          $('#createContainerSpinner').hide();
          Messages.error('Error', {}, d.message);
        } else {
          Container.start({id: d.Id}, {}, function (cd) {
            if (cd.message) {
              $('#createContainerSpinner').hide();
              Messages.error('Error', {}, cd.message);
            } else {
              $('#createContainerSpinner').hide();
              Messages.send('Container Started', d.Id);
              $state.go('containers', {}, {reload: true});
            }
          }, function (e) {
            $('#createContainerSpinner').hide();
            Messages.error("Failure", e, 'Unable to start container');
          });
        }
      }, function (e) {
        $('#createContainerSpinner').hide();
        Messages.error("Failure", e, 'Unable to create container');
      });
    }
  
    // TODO: centralize, already present in templatesController
    function pullImageAndCreateContainer(config) {
      Image.create($scope.imageConfig, function (data) {
        createContainer(config);
      }, function (e) {
        $('#createContainerSpinner').hide();
        Messages.error('Failure', e, 'Unable to pull image');
      });
    }
  
    function prepareImageConfig(config) {
      var image = config.Image;
      var registry = $scope.formValues.Registry;
      var imageConfig = ImageHelper.createImageConfigForContainer(image, registry);
      config.Image = imageConfig.fromImage + ':' + imageConfig.tag;
      $scope.imageConfig = imageConfig;
    }
  
    function preparePortBindings(config) {
      var bindings = {};
      config.HostConfig.PortBindings.forEach(function (portBinding) {
        if (portBinding.containerPort) {
          var key = portBinding.containerPort + "/" + portBinding.protocol;
          var binding = {};
          if (portBinding.hostPort && portBinding.hostPort.indexOf(':') > -1) {
            var hostAndPort = portBinding.hostPort.split(':');
            binding.HostIp = hostAndPort[0];
            binding.HostPort = hostAndPort[1];
          } else {
            binding.HostPort = portBinding.hostPort;
          }
          bindings[key] = [binding];
          config.ExposedPorts[key] = {};
        }
      });
      config.HostConfig.PortBindings = bindings;
    }
  
    function prepareConsole(config) {
      var value = $scope.formValues.Console;
      var openStdin = true;
      var tty = true;
      if (value === 'tty') {
        openStdin = false;
      } else if (value === 'interactive') {
        tty = false;
      } else if (value === 'none') {
        openStdin = false;
        tty = false;
      }
      config.OpenStdin = openStdin;
      config.Tty = tty;
    }
  
    function prepareEnvironmentVariables(config) {
      var env = [];
      config.Env.forEach(function (v) {
        if (v.name && v.value) {
          env.push(v.name + "=" + v.value);
        }
      });
      config.Env = env;
    }
  
    function prepareVolumes(config) {
      var binds = [];
      var volumes = {};
  
      $scope.formValues.Volumes.forEach(function (volume) {
        var name = volume.name;
        var containerPath = volume.containerPath;
        if (name && containerPath) {
          var bind = name + ':' + containerPath;
          volumes[containerPath] = {};
          if (volume.readOnly) {
            bind += ':ro';
          }
          binds.push(bind);
        }
      });
      config.HostConfig.Binds = binds;
      config.Volumes = volumes;
    }
  
    function prepareNetworkConfig(config) {
      var mode = config.HostConfig.NetworkMode;
      var container = $scope.formValues.NetworkContainer;
      var containerName = container;
      if (container && typeof container === 'object') {
        containerName = $filter('trimcontainername')(container.Names[0]);
        if ($scope.endpointMode.provider === 'DOCKER_SWARM') {
          containerName = $filter('swarmcontainername')(container);
        }
      }
      var networkMode = mode;
      if (containerName) {
        networkMode += ':' + containerName;
      }
      config.HostConfig.NetworkMode = networkMode;
    }
  
    function prepareLabels(config) {
      var labels = {};
      $scope.formValues.Labels.forEach(function (label) {
        if (label.name && label.value) {
          labels[label.name] = label.value;
        }
      });
      config.Labels = labels;
    }
  
    function prepareConfiguration() {
      var config = angular.copy($scope.config);
      prepareNetworkConfig(config);
      prepareImageConfig(config);
      preparePortBindings(config);
      prepareConsole(config);
      prepareEnvironmentVariables(config);
      prepareVolumes(config);
      prepareLabels(config);
      return config;
    }
  
    $scope.create = function () {
      var config = prepareConfiguration();
      $('#createContainerSpinner').show();
      if ($scope.formValues.alwaysPull) {
        pullImageAndCreateContainer(config);
      } else {
        createContainer(config);
      }
    };
  }]);
  