angular.module('templates', [])
.controller('TemplatesController', ['$scope', '$q', '$state', '$anchorScroll', 'Config', 'ContainerService', 'ImageService', 'NetworkService', 'TemplateService', 'TemplateHelper', 'VolumeService', 'Messages', 'Pagination',
function ($scope, $q, $state, $anchorScroll, Config, ContainerService, ImageService, NetworkService, TemplateService, TemplateHelper, VolumeService, Messages, Pagination) {
  $scope.state = {
    selectedTemplate: null,
    showAdvancedOptions: false,
    pagination_count: Pagination.getPaginationCount('templates')
  };
  $scope.formValues = {
    network: "",
    name: "",
  };

  $scope.changePaginationCount = function() {
    Pagination.setPaginationCount('templates', $scope.state.pagination_count);
  };

  $scope.addPortBinding = function() {
    $scope.state.selectedTemplate.Ports.push({ hostPort: '', containerPort: '', protocol: 'tcp' });
  };

  $scope.removePortBinding = function(index) {
    $scope.state.selectedTemplate.Ports.splice(index, 1);
  };

  $scope.createTemplate = function() {
    $('#createContainerSpinner').show();
    var template = $scope.state.selectedTemplate;
    var templateConfiguration = createTemplateConfiguration(template);

    VolumeService.createAutoGeneratedLocalVolumes(template.Volumes)
    .then(function success(data) {
      TemplateService.updateContainerConfigurationWithVolumes(templateConfiguration.container, template, data);
      return ImageService.pullImage(templateConfiguration.image);
    })
    .then(function success(data) {
      return ContainerService.createAndStartContainer(templateConfiguration.container);
    })
    .then(function success(data) {
      Messages.send('Container Started', data.Id);
      $state.go('containers', {}, {reload: true});
    })
    .catch(function error(err) {
      Messages.error('Failure', err, err.msg);
    })
    .finally(function final() {
      $('#createContainerSpinner').hide();
    });
  };

  var selectedItem = -1;
  $scope.selectTemplate = function(idx) {
    $('#template_' + idx).toggleClass("container-template--selected");
    if (selectedItem === idx) {
      unselectTemplate();
    } else {
      selectTemplate(idx);
    }
  };

  function unselectTemplate() {
    selectedItem = -1;
    $scope.state.selectedTemplate = null;
  }

  function selectTemplate(idx) {
    $('#template_' + selectedItem).toggleClass("container-template--selected");
    selectedItem = idx;
    var selectedTemplate = $scope.templates[idx];
    $scope.state.selectedTemplate = selectedTemplate;
    $anchorScroll('selectedTemplate');
  }

  function createTemplateConfiguration(template) {
    var network = $scope.formValues.network;
    var name = $scope.formValues.name;
    var containerMapping = determineContainerMapping(network);
    return TemplateService.createTemplateConfiguration(template, name, network, containerMapping);
  }

  function determineContainerMapping(network) {
    var endpointProvider = $scope.applicationState.endpoint.mode.provider;
    var containerMapping = 'BY_CONTAINER_IP';
    if (endpointProvider === 'DOCKER_SWARM' && network.Scope === 'global') {
      containerMapping = 'BY_SWARM_CONTAINER_NAME';
    } else if (network.Name !== "bridge") {
      containerMapping = 'BY_CONTAINER_NAME';
    }
  }

  function filterNetworksBasedOnProvider(networks) {
    var endpointProvider = $scope.applicationState.endpoint.mode.provider;
    if (endpointProvider === 'DOCKER_SWARM' || endpointProvider === 'DOCKER_SWARM_MODE') {
      networks = NetworkService.filterGlobalNetworks(networks);
      $scope.globalNetworkCount = networks.length;
      NetworkService.addPredefinedLocalNetworks(networks);
    } else {
      $scope.formValues.network = _.find(networks, function(o) { return o.Name === "bridge"; });
    }
    return networks;
  }

  function initTemplates() {
    Config.$promise.then(function (c) {
      $q.all({
        templates: TemplateService.getTemplates(),
        containers: ContainerService.getContainers(0, c.hiddenLabels),
        networks: NetworkService.getNetworks()
      })
      .then(function success(data) {
        $scope.templates = data.templates;
        $scope.runningContainers = data.containers;
        $scope.availableNetworks = filterNetworksBasedOnProvider(data.networks);
      })
      .catch(function error(err) {
        $scope.templates = [];
        Messages.error("Failure", err, "An error occured during apps initialization.");
      })
      .finally(function final(){
        $('#loadTemplatesSpinner').hide();
      });
    });
  }

  initTemplates();
}]);