// Start the application code itself.
quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics', 'angulartics.mixpanel', '$strap.directives'], function($provide) {
    $provide.factory('UserService', ['Restangular', function(Restangular) {
      var userResponse = {
        verified: false,
        anonymous: true,
        username: null,
        email: null,
        askForPassword: false,
      }

      var userService = {}

      userService.load = function() {
        var userFetch = Restangular.one('user/');
        userFetch.get().then(function(loadedUser) {
          userResponse = loadedUser;

          if (!userResponse.anonymous) {
            mixpanel.identify(userResponse.username);
            mixpanel.people.set({
              '$email': userResponse.email,
              '$username': userResponse.username,
              'verified': userResponse.verified
            });
            mixpanel.people.set_once({
              '$created': new Date()
            })
          }
        });
      };

      userService.currentUser = function() {
        return userResponse;
      }

      // Load the user the first time.
      userService.load();

      return userService;
    }]);

    $provide.factory('KeyService', ['$location', function($location) {
      var keyService = {}

      if ($location.host() === 'quay.io') {
        keyService['stripePublishableKey'] = 'pk_live_P5wLU0vGdHnZGyKnXlFG4oiu';
        keyService['githubClientId'] = '5a8c08b06c48d89d4d1e';
      } else {        
        keyService['stripePublishableKey'] = 'pk_test_uEDHANKm9CHCvVa2DLcipGRh';
        keyService['githubClientId'] = 'cfbc4aca88e5c1b40679';
      }

      return keyService;
    }]);

    $provide.factory('PlanService', ['Restangular', 'KeyService', function(Restangular, KeyService) {
      var plans = [
        {
          title: 'Open Source',
          price: 0,
          privateRepos: 0,
          stripeId: 'free',
          audience: 'Share with the world',
        },
        {
          title: 'Micro',
          price: 700,
          privateRepos: 5,
          stripeId: 'micro',
          audience: 'For smaller teams',
        },
        {
          title: 'Basic',
          price: 1200,
          privateRepos: 10,
          stripeId: 'small',
          audience: 'For your basic team',
        },
        {
          title: 'Medium',
          price: 2200,
          privateRepos: 20,
          stripeId: 'medium',
          audience: 'For medium-sized teams',
        },
      ];

      var planDict = {};
      var i;
      for(i = 0; i < plans.length; i++) {
        planDict[plans[i].stripeId] = plans[i];
      }

      var planService = {}

      planService.planList = function() {
        return plans;
      };

      planService.getPlan = function(planId) {
        return planDict[planId];
      };

      planService.getMinimumPlan = function(privateCount) {
        for (var i = 0; i < plans.length; i++) {
          var plan = plans[i];
          if (plan.privateRepos >= privateCount) {
            return plan;
          }
        }

        return null;
      };

      planService.showSubscribeDialog = function($scope, planId, started, success, failed) {
        var submitToken = function(token) {
          $scope.$apply(function() {
            started();
          });

          mixpanel.track('plan_subscribe');

          var subscriptionDetails = {
            token: token.id,
            plan: planId,
          };

          var createSubscriptionRequest = Restangular.one('user/plan');
          $scope.$apply(function() {
            createSubscriptionRequest.customPUT(subscriptionDetails).then(success, failed);
          });
        };

        var planDetails = planService.getPlan(planId)
        StripeCheckout.open({
          key:         KeyService.stripePublishableKey,
          address:     false, // TODO change to true
          amount:      planDetails.price,
          currency:    'usd',
          name:        'Quay ' + planDetails.title + ' Subscription',
          description: 'Up to ' + planDetails.privateRepos + ' private repositories',
          panelLabel:  'Subscribe',
          token:       submitToken
        });
      };

      return planService;
    }]);
  }).
  directive('match', function($parse) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ctrl) {
        scope.$watch(function() {        
          return $parse(attrs.match)(scope) === ctrl.$modelValue;
        }, function(currentValue) {
          ctrl.$setValidity('mismatch', currentValue);
        });
      }
    };
  }).
  directive('onresize', function ($window, $parse) {
    return function (scope, element, attr) {
      var fn = $parse(attr.onresize);

      var notifyResized = function() {
        scope.$apply(function () {
          fn(scope);
        });
      };

      angular.element($window).on('resize', null, notifyResized);

      scope.$on('$destroy', function() {
        angular.element($window).off('resize', null, notifyResized);
      });
    };
  }).
  config(['$routeProvider', '$locationProvider', '$analyticsProvider',
    function($routeProvider, $locationProvider, $analyticsProvider) {

    $analyticsProvider.virtualPageviews(true);

    $locationProvider.html5Mode(true);

    // WARNING WARNING WARNING
    // If you add a route here, you must add a corresponding route in thr endpoints/web.py
    // index rule to make sure that deep links directly deep into the app continue to work.
    // WARNING WARNING WARNING
    $routeProvider.
      when('/repository/:namespace/:name', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl, reloadOnSearch: false}).
      when('/repository/:namespace/:name/tag/:tag', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl}).
      when('/repository/:namespace/:name/image/:image', {templateUrl: '/static/partials/image-view.html', controller: ImageViewCtrl}).
      when('/repository/:namespace/:name/admin', {templateUrl: '/static/partials/repo-admin.html', controller:RepoAdminCtrl}).
      when('/repository/', {title: 'Repositories', templateUrl: '/static/partials/repo-list.html', controller: RepoListCtrl}).
      when('/user/', {title: 'User Admin', templateUrl: '/static/partials/user-admin.html', controller: UserAdminCtrl}).
      when('/guide/', {title: 'User Guide', templateUrl: '/static/partials/guide.html', controller: GuideCtrl}).
      when('/plans/', {title: 'Plans and Pricing', templateUrl: '/static/partials/plans.html', controller: PlansCtrl}).
      when('/signin/', {title: 'Signin', templateUrl: '/static/partials/signin.html', controller: SigninCtrl}).
      when('/new/', {title: 'Create new repository', templateUrl: '/static/partials/new-repo.html', controller: NewRepoCtrl}).

      when('/v1/', {title: 'Activation information', templateUrl: '/static/partials/v1-page.html', controller: V1Ctrl}).

      when('/', {title: 'Hosted Private Docker Registry', templateUrl: '/static/partials/landing.html', controller: LandingCtrl}).
      otherwise({redirectTo: '/'});
  }]).
  config(function(RestangularProvider) {
    RestangularProvider.setBaseUrl('/api/');
  });

quayApp.directive('repoCircle', function () {
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/repo-circle.html',
    replace: false,
    transclude: false,
    restrict: 'C',
    scope: {
      'repo': '=repo'
    },
    controller: function($scope, $element) {
    }
  };
  return directiveDefinitionObject;
});


quayApp.directive('buildStatus', function () {
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/build-status.html',
    replace: false,
    transclude: false,
    restrict: 'C',
    scope: {
      'build': '=build'
    },
    controller: function($scope, $element) {
        $scope.getBuildProgress = function(buildInfo) {
            switch (buildInfo.status) {
              case 'building':
                return (buildInfo.current_command / buildInfo.total_commands) * 100;
                break;
                
              case 'pushing':
                var imagePercentDecimal = (buildInfo.image_completion_percent / 100);
                return ((buildInfo.current_image + imagePercentDecimal) / buildInfo.total_images) * 100;
                break;

              case 'complete':
                return 100;
                break;

              case 'initializing':
              case 'starting':
              case 'waiting':
                return 0;
                break;
            }
            
            return -1;
        };

        $scope.getBuildMessage = function(buildInfo) {
            switch (buildInfo.status) {
            case 'initializing':
                return 'Starting Dockerfile build';
                break;

            case 'starting':
            case 'waiting':
            case 'building':
                return 'Building image from Dockerfile';
                break;

            case 'pushing':
                return 'Pushing image built from Dockerfile';
                break;

            case 'complete':
                return 'Dockerfile build completed and pushed';
                break;
                
            case 'error':
                return 'Dockerfile build failed: ' + buildInfo.message;
                break;
            }
        };
    }
  };
  return directiveDefinitionObject;
});

quayApp.run(['$location', '$rootScope', function($location, $rootScope) {
  $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
    if (current.$$route.title) {
      $rootScope.title = current.$$route.title;
    }
  });
}]);