(function() {
  /**
   * The superuser admin page provides a new management UI for Quay Enterprise.
   */
  angular.module('quayPages').config(['pages', function(pages) {
    pages.create('superuser', 'super-user.html', SuperuserCtrl,
      {
        'newLayout': true,
        'title': 'Quay Enterprise Management'
      })
  }]);

  function SuperuserCtrl($scope, $timeout, ApiService, Features, UserService, ContainerService, AngularPollChannel, CoreDialog) {
    if (!Features.SUPER_USERS) {
      return;
    }

    // Monitor any user changes and place the current user into the scope.
    UserService.updateUserIn($scope);

    $scope.configStatus = null;
    $scope.requiresRestart = null;
    $scope.logsCounter = 0;
    $scope.newUser = {};
    $scope.createdUser = null;
    $scope.changeLog = null;
    $scope.debugServices = null;
    $scope.debugLogs = null;
    $scope.pollChannel = null;
    $scope.logsScrolled = false;
    $scope.csrf_token = encodeURIComponent(window.__token);
    $scope.dashboardActive = false;
    $scope.currentConfig = null;
    $scope.serviceKeysActive = false;

    $scope.setDashboardActive = function(active) {
      $scope.dashboardActive = active;
    };

    $scope.configurationSaved = function(config) {
      $scope.currentConfig = config;
      $scope.requiresRestart = true;
    };

    $scope.showCreateUser = function() {
      $scope.createdUser = null;
      $('#createUserModal').modal('show');
    };

    $scope.loadServiceKeys = function() {
      $scope.serviceKeysActive = true;
    };

    $scope.viewSystemLogs = function(service) {
      if ($scope.pollChannel) {
        $scope.pollChannel.stop();
      }

      $scope.debugService = service;
      $scope.debugLogs = null;

      $scope.pollChannel = AngularPollChannel.create($scope, $scope.loadServiceLogs, 2 * 1000 /* 2s */);
      $scope.pollChannel.start();
    };

    $scope.loadServiceLogs = function(callback) {
      if (!$scope.debugService) { return; }

      var params = {
        'service': $scope.debugService
      };

      var errorHandler = ApiService.errorDisplay('Cannot load system logs. Please contact support.',
        function() {
          callback(false);
        })

      ApiService.getSystemLogs(null, params, /* background */true).then(function(resp) {
        $scope.debugLogs = resp['logs'];
        callback(true);
      }, errorHandler);
    };

    $scope.loadDebugServices = function() {
      if ($scope.pollChannel) {
        $scope.pollChannel.stop();
      }

      $scope.debugService = null;

      ApiService.listSystemLogServices().then(function(resp) {
        $scope.debugServices = resp['services'];
      }, ApiService.errorDisplay('Cannot load system logs. Please contact support.'))
    };

    $scope.getChangeLog = function() {
      if ($scope.changeLog) { return; }

      ApiService.getChangeLog().then(function(resp) {
        $scope.changeLog = resp;
      }, ApiService.errorDisplay('Cannot load change log. Please contact support.'))
    }

    $scope.loadUsageLogs = function() {
      $scope.logsCounter++;
    };

    $scope.loadOrganizations = function() {
      if ($scope.organizations) {
        return;
      }

      $scope.loadOrganizationsInternal();
    };

    $scope.loadOrganizationsInternal = function() {
      $scope.organizationsResource = ApiService.listAllOrganizationsAsResource().get(function(resp) {
        $scope.organizations = resp['organizations'];
        return $scope.organizations;
      });
    };

    $scope.loadUsers = function() {
      if ($scope.users) {
        return;
      }

      $scope.loadUsersInternal();
    };

    $scope.loadUsersInternal = function() {
      ApiService.listAllUsers().then(function(resp) {
        $scope.users = resp['users'];
        $scope.showInterface = true;
      }, function(resp) {
        $scope.users = [];
        $scope.usersError = ApiService.getErrorMessage(resp);
      });
    };

    $scope.showChangePassword = function(user) {
      $scope.userToChange = user;
      $('#changePasswordModal').modal({});
    };

    $scope.showChangeEmail = function(user) {
      $scope.userToChange = user;
      $('#changeEmailModal').modal({});
    };

    $scope.createUser = function() {
      $scope.creatingUser = true;
      $scope.createdUser = null;

      var errorHandler = ApiService.errorDisplay('Cannot create user', function() {
        $scope.creatingUser = false;
        $('#createUserModal').modal('hide');
      });

      ApiService.createInstallUser($scope.newUser, null).then(function(resp) {
        $scope.creatingUser = false;
        $scope.newUser = {};
        $scope.createdUser = resp;
        $scope.loadUsersInternal();
      }, errorHandler)
    };

    $scope.setSuperuser = function(user, status) {
      var setSuperuser = function() {
        var params = {
          'username': user.username
        };

        var data = {
          'superuser': status
        };

        ApiService.changeInstallUser(data, params).then(function(resp) {
          $scope.requiresRestart = true;
        }, ApiService.errorDisplay('Could not change user'));
      };

      var msg = 'Note: This change, once applied, will require your installation ' +
                'to be restarted to take effect';

      bootbox.confirm(msg, function(status) {
        if (status) {
          setSuperuser();
        }
      });
    };

    $scope.showDeleteUser = function(user) {
      if (user.username == UserService.currentUser().username) {
        bootbox.dialog({
          "message": 'Cannot delete yourself!',
          "title": "Cannot delete user",
          "buttons": {
            "close": {
              "label": "Close",
              "className": "btn-primary"
            }
          }
        });
        return;
      }

      $scope.userToDelete = user;
      $('#confirmDeleteUserModal').modal({});
    };

    $scope.changeUserEmail = function(user) {
      $('#changeEmailModal').modal('hide');

      var params = {
        'username': user.username
      };

      var data = {
        'email': user.newemail
      };

      ApiService.changeInstallUser(data, params).then(function(resp) {
        $scope.loadUsersInternal();
        user.email = user.newemail;
        delete user.newemail;
      }, ApiService.errorDisplay('Could not change user'));
    };

    $scope.askDeleteOrganization = function(org) {
      bootbox.confirm('Are you sure you want to delete this organization? Its data will be deleted with it.',
        function(result) {
          if (!result) { return; }

          var params = {
            'name': org.name
          };

          ApiService.deleteOrganization(null, params).then(function(resp) {
            $scope.loadOrganizationsInternal();
          }, ApiService.errorDisplay('Could not delete organization'));
        });
    };

    $scope.askRenameOrganization = function(org) {
      bootbox.prompt('Enter a new name for the organization:', function(newName) {
        if (!newName) { return; }

        var params = {
          'name': org.name
        };

        var data = {
          'name': newName
        };

        ApiService.changeOrganization(data, params).then(function(resp) {
          $scope.loadOrganizationsInternal();
          org.name = newName;
        }, ApiService.errorDisplay('Could not rename organization'));
      });
    };

    $scope.askDisableUser = function(user) {
      var message = 'Are you sure you want to disable this user? ' +
                    'They will be unable to login, pull or push.'

      if (!user.enabled) {
        message = 'Are you sure you want to reenable this user? ' +
                  'They will be able to login, pull or push.'
      }

      bootbox.confirm(message, function(resp) {
        if (resp) {
          var params = {
            'username': user.username
          };

          var data = {
            'enabled': !user.enabled
          };

          ApiService.changeInstallUser(data, params).then(function(resp) {
            $scope.loadUsersInternal();
          });
        }
      });
    };

    $scope.changeUserPassword = function(user) {
      $('#changePasswordModal').modal('hide');

      var params = {
        'username': user.username
      };

      var data = {
        'password': user.password
      };

      ApiService.changeInstallUser(data, params).then(function(resp) {
        $scope.loadUsersInternal();
      }, ApiService.errorDisplay('Could not change user'));
    };

    $scope.deleteUser = function(user) {
      $('#confirmDeleteUserModal').modal('hide');

      var params = {
        'username': user.username
      };

      ApiService.deleteInstallUser(null, params).then(function(resp) {
        $scope.loadUsersInternal();
      }, ApiService.errorDisplay('Cannot delete user'));
    };

    $scope.sendRecoveryEmail = function(user) {
      var params = {
        'username': user.username
      };

      ApiService.sendInstallUserRecoveryEmail(null, params).then(function(resp) {
        bootbox.dialog({
          "message": "A recovery email has been sent to " + resp['email'],
          "title": "Recovery email sent",
          "buttons": {
            "close": {
              "label": "Close",
              "className": "btn-primary"
            }
          }
        });

      }, ApiService.errorDisplay('Cannot send recovery email'))
    };

    $scope.restartContainer = function() {
      $('#restartingContainerModal').modal({
        keyboard: false,
        backdrop: 'static'
      });

      ContainerService.restartContainer(function() {
        $scope.checkStatus()
      });
    };

    $scope.checkStatus = function() {
      ContainerService.checkStatus(function(resp) {
        $('#restartingContainerModal').modal('hide');
        $scope.configStatus = resp['status'];
        $scope.requiresRestart = resp['requires_restart'];

        if ($scope.configStatus == 'ready') {
          $scope.currentConfig = null;
          $scope.loadUsers();
        } else {
          var message = "Installation of this product has not yet been completed." +
                        "<br><br>Please read the " +
                        "<a href='https://coreos.com/docs/enterprise-registry/initial-setup/'>" +
                        "Setup Guide</a>"

          var title = "Installation Incomplete";
          CoreDialog.fatal(title, message);
        }
      }, $scope.currentConfig);
    };

    // Load the initial status.
    $scope.checkStatus();
  }
}());