/**
 * An element which displays those images which belong to the specified tag *only*. If an image
 * is shared between more than a single tag in the repository, then it is not displayed.
 */
angular.module('quay').directive('tagSpecificImagesView', function () {
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/tag-specific-images-view.html',
    replace: false,
    transclude: true,
    restrict: 'C',
    scope: {
      'repository': '=repository',
      'tag': '=tag',
      'images': '=images',
      'imageCutoff': '=imageCutoff'
    },
    controller: function($scope, $element, UtilService) {
      $scope.getFirstTextLine = UtilService.getFirstMarkdownLineAsText;

      $scope.hasImages = false;
      $scope.tagSpecificImages = [];

      $scope.getImageListingClasses = function(image) {
        var classes = '';
        if (image.ancestors.length > 1) {
          classes += 'child ';
        }

        var currentTag = $scope.repository.tags[$scope.tag];
        if (image.id == currentTag.image_id) {
          classes += 'tag-image ';
        }

        return classes;
      };

      var forAllTagImages = function(tag, callback, opt_cutoff) {
        if (!tag) { return; }

        if (!$scope.imageByDockerId) {
          $scope.imageByDockerId = [];
          for (var i = 0; i < $scope.images.length; ++i) {
            var currentImage = $scope.images[i];
            $scope.imageByDockerId[currentImage.id] = currentImage;
          }
        }

        var tag_image = $scope.imageByDockerId[tag.image_id];
        if (!tag_image) {
          return;
        }

        callback(tag_image);

        var ancestors = tag_image.ancestors.split('/').reverse();
        for (var i = 0; i < ancestors.length; ++i) {
          var image = $scope.imageByDockerId[ancestors[i]];
          if (image) {
            if (image == opt_cutoff) {
              return;
            }

            callback(image);
          }
        }
      };

      var refresh = function() {
        if (!$scope.repository || !$scope.tag || !$scope.images) {
          $scope.tagSpecificImages = [];
          return;
        }

        var tag = $scope.repository.tags[$scope.tag];
        if (!tag) {
          $scope.tagSpecificImages = [];
          return;
        }

        var getIdsForTag = function(currentTag) {
          var ids = {};
          forAllTagImages(currentTag, function(image) {
            ids[image.id] = true;
          }, $scope.imageCutoff);
          return ids;
        };

        // Remove any IDs that match other tags.
        var toDelete = getIdsForTag(tag);
        for (var currentTagName in $scope.repository.tags) {
          var currentTag = $scope.repository.tags[currentTagName];
          if (currentTag != tag) {
            for (var id in getIdsForTag(currentTag)) {
              delete toDelete[id];
            }
          }
        }

        // Return the matching list of images.
        var images = [];
        for (var i = 0; i < $scope.images.length; ++i) {
          var image = $scope.images[i];
          if (toDelete[image.id]) {
            images.push(image);
          }
        }

        images.sort(function(a, b) {
          var result = new Date(b.created) - new Date(a.created);
          if (result != 0) {
            return result;
          }

          return b.sort_index - a.sort_index;
        });

        $scope.tagSpecificImages = images;
      };

      $scope.$watch('repository', refresh);
      $scope.$watch('tag', refresh);
      $scope.$watch('images', refresh);
    }
  };
  return directiveDefinitionObject;
});
