# Path: src/ctf_gameserver/web/registration/models.py
# class Team(models.Model):
#     """
#     Database representation of a team participating in the competition.
#     This enhances the user model, where the team name, password, formal email address etc. are stored. It is
#     particularly attuned to django.contrib.auth.models.User, but should work with other user models as well.
#     """
# 
#     user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, on_delete=models.CASCADE)
# 
#     net_number = models.PositiveSmallIntegerField(null=True, unique=True)
#     informal_email = models.EmailField(_('Informal email address'))
#     image = ThumbnailImageField(upload_to=_gen_image_name, blank=True)
#     affiliation = models.CharField(max_length=100, blank=True)
#     country = models.CharField(max_length=100)
#     # NOP teams don't get included in the scoring
#     nop_team = models.BooleanField(default=False, db_index=True)
# 
#     class ActiveObjectsManager(models.Manager):
#         def get_queryset(self):
#             return super().get_queryset().filter(user__is_active=True)
# 
#     class ActiveNotNopObjectsManager(ActiveObjectsManager):
#         def get_queryset(self):
#             return super().get_queryset().filter(nop_team=False)
# 
#     # The first Manager in a class is used as default
#     objects = models.Manager()
#     # QuerySet that only returns Teams whose associated user object is not marked as inactive
#     active_objects = ActiveObjectsManager()
#     # QuerySet that only returns active Teams that are not marked as NOP team
#     active_not_nop_objects = ActiveNotNopObjectsManager()
# 
#     def __str__(self):
#         # pylint: disable=no-member
#         return self.user.username
# 
# Path: src/ctf_gameserver/web/registration/admin.py
# class InlineTeamAdmin(admin.StackedInline):
#     """
#     InlineModelAdmin for Team objects. Primarily designed to be used within a UserAdmin.
#     """
# 
#     model = Team
#     form = AdminTeamForm
# 
#     # Abuse the plural title as headline, since more than one team will never be edited using this inline
#     verbose_name_plural = _('Associated team')
# 
# Path: src/ctf_gameserver/web/scoring/models.py
# class GameControl(models.Model):
#     """
#     Single-row database table to store control information for the competition.
#     """
# 
#     competition_name = models.CharField(max_length=100, default='My A/D CTF')
#     # Start and end times for the whole competition: Make them NULL-able (for the initial state), but not
#     # blank-able (have to be set upon editing); "services_public" is the point at which information about the
#     # services is public, but the actual game has not started yet
#     services_public = models.DateTimeField(null=True)
#     start = models.DateTimeField(null=True)
#     end = models.DateTimeField(null=True)
#     # Tick duration in seconds
#     tick_duration = models.PositiveSmallIntegerField(default=180)
#     # Number of ticks a flag is valid for including the one it was generated in
#     valid_ticks = models.PositiveSmallIntegerField(default=5)
#     current_tick = models.IntegerField(default=-1)
#     flag_prefix = models.CharField(max_length=20, default='FLAG_')
#     registration_open = models.BooleanField(default=False)
#     registration_confirm_text = models.TextField(blank=True)
#     min_net_number = models.PositiveIntegerField(null=True, blank=True)
#     max_net_number = models.PositiveIntegerField(null=True, blank=True)
# 
#     class Meta:
#         verbose_name_plural = 'Game control'
# 
#     @classmethod
#     def get_instance(cls):
#         try:
#             return cls.objects.get()
#         except cls.DoesNotExist:
#             game_control = GameControl()
#             game_control.save()
#             return game_control
# 
#     def clean(self):
#         """
#         Ensures that only one instance of the class gets created.
#         Inspired by https://stackoverflow.com/a/6436008.
#         """
#         cls = self.__class__
# 
#         if cls.objects.count() > 0 and self.id != cls.objects.get().id:
#             # pylint: disable=no-member
#             raise ValidationError(_('Only a single instance of {cls} can be created')
#                                   .format(cls=cls.__name__))
# 
#     def are_services_public(self):
#         """
#         Indicates whether information about the services is public yet.
#         """
#         if self.services_public is None:
#             return False
# 
#         return self.services_public <= timezone.now()
# 
#     def competition_started(self):
#         """
#         Indicates whether the competition has already begun (i.e. running or over).
#         """
#         if self.start is None or self.end is None:
#             return False
# 
#         return self.start <= timezone.now()
# 
#     def competition_over(self):
#         """
#         Indicates whether the competition is already over.
#         """
#         if self.start is None or self.end is None:
#             return False
# 
#         return self.end < timezone.now()
# 
# Path: src/ctf_gameserver/web/util.py
# def _format_proxy(proxy, *args, **kwargs):


from django.contrib import admin
from django.utils.functional import classproperty
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from .registration.models import Team
from .registration.admin import InlineTeamAdmin
from .scoring.models import GameControl
from .util import format_lazy



class CTFAdminSite(admin.AdminSite):
    """
    Custom variant of the AdminSite which replaces the default headers and titles.
    """

    index_title = _('Administration home')

    # Declare this lazily through a classproperty in order to avoid a circular dependency when creating
    # migrations
    @classproperty
    def site_header(cls):    # pylint: disable=no-self-argument

# Path: src/ctf_gameserver/web/registration/models.py
# class Team(models.Model):
#     """
#     Database representation of a team participating in the competition.
#     This enhances the user model, where the team name, password, formal email address etc. are stored. It is
#     particularly attuned to django.contrib.auth.models.User, but should work with other user models as well.
#     """
# 
#     user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, on_delete=models.CASCADE)
# 
#     net_number = models.PositiveSmallIntegerField(null=True, unique=True)
#     informal_email = models.EmailField(_('Informal email address'))
#     image = ThumbnailImageField(upload_to=_gen_image_name, blank=True)
#     affiliation = models.CharField(max_length=100, blank=True)
#     country = models.CharField(max_length=100)
#     # NOP teams don't get included in the scoring
#     nop_team = models.BooleanField(default=False, db_index=True)
# 
#     class ActiveObjectsManager(models.Manager):
#         def get_queryset(self):
#             return super().get_queryset().filter(user__is_active=True)
# 
#     class ActiveNotNopObjectsManager(ActiveObjectsManager):
#         def get_queryset(self):
#             return super().get_queryset().filter(nop_team=False)
# 
#     # The first Manager in a class is used as default
#     objects = models.Manager()
#     # QuerySet that only returns Teams whose associated user object is not marked as inactive
#     active_objects = ActiveObjectsManager()
#     # QuerySet that only returns active Teams that are not marked as NOP team
#     active_not_nop_objects = ActiveNotNopObjectsManager()
# 
#     def __str__(self):
#         # pylint: disable=no-member
#         return self.user.username
# 
# Path: src/ctf_gameserver/web/registration/admin.py
# class InlineTeamAdmin(admin.StackedInline):
#     """
#     InlineModelAdmin for Team objects. Primarily designed to be used within a UserAdmin.
#     """
# 
#     model = Team
#     form = AdminTeamForm
# 
#     # Abuse the plural title as headline, since more than one team will never be edited using this inline
#     verbose_name_plural = _('Associated team')
# 
# Path: src/ctf_gameserver/web/scoring/models.py
# class GameControl(models.Model):
#     """
#     Single-row database table to store control information for the competition.
#     """
# 
#     competition_name = models.CharField(max_length=100, default='My A/D CTF')
#     # Start and end times for the whole competition: Make them NULL-able (for the initial state), but not
#     # blank-able (have to be set upon editing); "services_public" is the point at which information about the
#     # services is public, but the actual game has not started yet
#     services_public = models.DateTimeField(null=True)
#     start = models.DateTimeField(null=True)
#     end = models.DateTimeField(null=True)
#     # Tick duration in seconds
#     tick_duration = models.PositiveSmallIntegerField(default=180)
#     # Number of ticks a flag is valid for including the one it was generated in
#     valid_ticks = models.PositiveSmallIntegerField(default=5)
#     current_tick = models.IntegerField(default=-1)
#     flag_prefix = models.CharField(max_length=20, default='FLAG_')
#     registration_open = models.BooleanField(default=False)
#     registration_confirm_text = models.TextField(blank=True)
#     min_net_number = models.PositiveIntegerField(null=True, blank=True)
#     max_net_number = models.PositiveIntegerField(null=True, blank=True)
# 
#     class Meta:
#         verbose_name_plural = 'Game control'
# 
#     @classmethod
#     def get_instance(cls):
#         try:
#             return cls.objects.get()
#         except cls.DoesNotExist:
#             game_control = GameControl()
#             game_control.save()
#             return game_control
# 
#     def clean(self):
#         """
#         Ensures that only one instance of the class gets created.
#         Inspired by https://stackoverflow.com/a/6436008.
#         """
#         cls = self.__class__
# 
#         if cls.objects.count() > 0 and self.id != cls.objects.get().id:
#             # pylint: disable=no-member
#             raise ValidationError(_('Only a single instance of {cls} can be created')
#                                   .format(cls=cls.__name__))
# 
#     def are_services_public(self):
#         """
#         Indicates whether information about the services is public yet.
#         """
#         if self.services_public is None:
#             return False
# 
#         return self.services_public <= timezone.now()
# 
#     def competition_started(self):
#         """
#         Indicates whether the competition has already begun (i.e. running or over).
#         """
#         if self.start is None or self.end is None:
#             return False
# 
#         return self.start <= timezone.now()
# 
#     def competition_over(self):
#         """
#         Indicates whether the competition is already over.
#         """
#         if self.start is None or self.end is None:
#             return False
# 
#         return self.end < timezone.now()
# 
# Path: src/ctf_gameserver/web/util.py
# def _format_proxy(proxy, *args, **kwargs):


# Path: src/ctf_gameserver/web/admin.py
from django.contrib import admin
from django.utils.functional import classproperty
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from .registration.models import Team
from .registration.admin import InlineTeamAdmin
from .scoring.models import GameControl
from .util import format_lazy




class CTFAdminSite(admin.AdminSite):
    """
    Custom variant of the AdminSite which replaces the default headers and titles.
    """

    index_title = _('Administration home')

    # Declare this lazily through a classproperty in order to avoid a circular dependency when creating
    # migrations
    @classproperty
    def site_header(cls):    # pylint: disable=no-self-argument

        return format_lazy(_('{competition_name} administration'),