(function() {
  /**
   * Repository listing page. Shows all repositories for all visibile namespaces.
   */
  angular.module('quayPages').config(['pages', function(pages) {
    pages.create('repo-list', 'repo-list.html', RepoListCtrl, {
      'newLayout': true,
      'title': 'Repositories',
      'description': 'View and manage Docker repositories'
    }, ['layout'])

    pages.create('repo-list', 'old-repo-list.html', OldRepoListCtrl, {
      'title': 'Repositories',
      'description': 'View and manage Docker repositories'
    }, ['old-layout']);
  }]);


  function RepoListCtrl($scope, $sanitize, $q, Restangular, UserService, ApiService) {
    $scope.namespace = null;
    $scope.page = 1;
    $scope.publicPageCount = null;
    $scope.allRepositories = {};
    $scope.loading = true;

    // When loading the UserService, if the user is logged in, create a list of
    // relevant namespaces and collect the relevant repositories.
    UserService.updateUserIn($scope, function(user) {
      $scope.loading = false;
      if (!user.anonymous) {
        // Add our user to our list of namespaces.
        $scope.namespaces = [{
          'name': user.username,
          'avatar': user.avatar
        }];

        // Add each org to our list of namespaces.
        user.organizations.map(function(org) {
          $scope.namespaces.push({
            'name': org.name,
            'avatar': org.avatar
          });
        });

        // Load the repos.
        loadStarredRepos();
        loadRepos();
      }
    });

    $scope.isOrganization = function(namespace) {
      return !!UserService.getOrganization(namespace);
    };

    $scope.starToggled = function(repo) {
      if (repo.is_starred) {
        $scope.starred_repositories.value.push(repo);
      } else {
        $scope.starred_repositories.value = $scope.starred_repositories.value.filter(function(repo) {
          return repo.is_starred;
        });
      }
    };

    // Finds a duplicate repo if it exists. If it doesn't, inserts the repo.
    var findDuplicateRepo = function(repo) {
      var found = $scope.allRepositories[repo.namespace + '/' + repo.name];
      if (found) {
        return found;
      } else {
        $scope.allRepositories[repo.namespace + '/' + repo.name] = repo;
        return repo;
      }
    };

    var loadStarredRepos = function() {
      if (!$scope.user || $scope.user.anonymous) {
        return;
      }

      $scope.starred_repositories = ApiService.listStarredReposAsResource().get(function(resp) {
        return resp.repositories.map(function(repo) {
          repo = findDuplicateRepo(repo);
          repo.is_starred = true;
          return repo;
        });
      });
    };

    var loadRepos = function() {
      if (!$scope.user || $scope.user.anonymous || $scope.namespaces.length == 0) {
        return;
      }

      $scope.namespaces.map(function(namespace) {
        var options = {
          'public': false,
          'sort': true,
          'namespace': namespace.name,
        };

        namespace.repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
          return resp.repositories.map(findDuplicateRepo);
        });
      });
    };
  }

  function OldRepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
    $scope.namespace = null;
    $scope.page = 1;
    $scope.publicPageCount = null;

    // Monitor changes in the user.
    UserService.updateUserIn($scope, function() {
      loadMyRepos($scope.namespace);
    });

    // Monitor changes in the namespace.
    $scope.$watch('namespace', function(namespace) {
      loadMyRepos(namespace);
    });

    $scope.movePublicPage = function(increment) {
      if ($scope.publicPageCount == null) {
        return;
      }

      $scope.page += increment;
      if ($scope.page < 1) {
        $scope.page = 1;
      }

      if ($scope.page > $scope.publicPageCount) {
        $scope.page = $scope.publicPageCount;
      }

      loadPublicRepos();
    };

    var loadMyRepos = function(namespace) {
      if (!$scope.user || $scope.user.anonymous || !namespace) {
        return;
      }

      var options = {'public': false, 'sort': true, 'namespace': namespace};

      $scope.user_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
        return resp.repositories;
      });
    };

    var loadPublicRepos = function() {
      var options = {
        'public': true,
        'private': false,
        'sort': true,
        'limit': 10,
        'page': $scope.page,
        'count': $scope.page == 1
      };

      $scope.public_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
        if (resp.count) {
          $scope.publicPageCount = Math.ceil(resp.count / 10);
        }
        return resp.repositories;
      });
    };

    loadPublicRepos();
  }
})();