# Path: lambdainst/models.py
# class VPNUser(models.Model):
#     class Meta:
#         verbose_name = _("VPN User")
#         verbose_name_plural = _("VPN Users")
# 
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
#     notes = models.TextField(blank=True)
# 
#     expiration = models.DateTimeField(blank=True, null=True)
#     last_expiry_notice = models.DateTimeField(blank=True, null=True)
#     notify_expiration = models.BooleanField(default=True)
# 
#     trial_periods_given = models.IntegerField(default=0)
# 
#     last_vpn_auth = models.DateTimeField(blank=True, null=True)
# 
#     referrer = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL,
#                                  related_name='referrals')
#     referrer_used = models.BooleanField(default=False)
#     campaign = models.CharField(blank=True, null=True, max_length=64)
# 
#     @property
#     def is_paid(self):
#         if self.get_subscription():
#             return True
#         if not self.expiration:
#             return False
#         return self.expiration > timezone.now()
# 
#     @property
#     def time_left(self):
#         return timezone.now() - self.expiration
# 
#     def add_paid_time(self, time):
#         now = timezone.now()
#         if not self.expiration or self.expiration < now:
#             self.expiration = now
#         self.expiration += time
# 
#         # Propagate update to core
#         if core.VPN_AUTH_STORAGE == 'core':
#             core.update_user_expiration(self.user)
# 
#     def give_trial_period(self):
#         self.add_paid_time(get_trial_period_duration())
#         self.trial_periods_given += 1
# 
#     @property
#     def can_have_trial(self):
#         if self.trial_periods_given >= site_config.TRIAL_PERIOD_MAX:
#             return False
#         if self.user.payment_set.filter(status='confirmed').count() > 0:
#             return False
#         return True
# 
#     @property
#     def remaining_trial_periods(self):
#         return site_config.TRIAL_PERIOD_MAX - self.trial_periods_given
# 
#     def on_payment_confirmed(self, payment):
#         if self.referrer and not self.referrer_used:
#             self.referrer.vpnuser.add_paid_time(timedelta(days=14))
#             self.referrer.vpnuser.save()
#             self.referrer_used = True
# 
#     def get_subscription(self, include_unconfirmed=False):
#         """ Tries to get the active (and most recent) Subscription """
#         s = Subscription.objects.filter(user=self.user, status='active') \
#                                 .order_by('-id') \
#                                 .first()
#         if s is not None or include_unconfirmed is False:
#             return s
#         s = Subscription.objects.filter(user=self.user, status='unconfirmed') \
#                                 .order_by('-id') \
#                                 .first()
#         return s
# 
#     def __str__(self):
#         return self.user.username
# 
# class GiftCode(models.Model):
#     class Meta:
#         verbose_name = _("Gift Code")
#         verbose_name_plural = _("Gift Codes")
# 
#     code = models.CharField(max_length=32, default=random_gift_code)
#     time = models.DurationField(default=timedelta(days=30))
#     created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
#     created_by = models.ForeignKey(User, related_name='created_giftcode_set',
#                                    on_delete=models.CASCADE, null=True, blank=True)
#     single_use = models.BooleanField(default=True)
#     free_only = models.BooleanField(default=True)
#     available = models.BooleanField(default=True)
#     comment = models.TextField(blank=True)
#     users = models.ManyToManyField(User, through='GiftCodeUser')
# 
#     def use_on(self, user):
#         if not self.available:
#             return False
#         if self.free_only and user.vpnuser.is_paid:
#             return False
# 
#         link = GiftCodeUser(user=user, code=self)
#         link.save()
# 
#         user.vpnuser.add_paid_time(self.time)
#         user.vpnuser.save()
# 
#         if self.single_use:
#             self.available = False
# 
#         self.save()
# 
#         return True
# 
#     @property
#     def comment_head(self):
#         head = self.comment.split('\n', 1)[0]
#         if len(head) > 80:
#             head = head[:80] + "..."
#         return head
# 
#     def __str__(self):
#         return self.code
# 
# class GiftCodeUser(models.Model):
#     class Meta:
#         verbose_name = _("Gift Code User")
#         verbose_name_plural = _("Gift Code Users")
# 
#     user = models.ForeignKey(User)
#     code = models.ForeignKey(GiftCode)
#     date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
# 
#     def __str__(self):
#         return "%s (%s)" % (self.user.username, self.code.code)


import string
from django.shortcuts import resolve_url
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from lambdainst.models import VPNUser, GiftCode, GiftCodeUser
from . import core



def make_user_link(user):
    change_url = resolve_url('admin:auth_user_change', user.id)
    return '<a href="%s">%s</a>' % (change_url, user.username)


class GiftCodeAdminForm(forms.ModelForm):
    def clean(self):
        input_code = self.cleaned_data.get('code', '')
        code_charset = string.ascii_letters + string.digits
        if any(c not in code_charset for c in input_code):
            raise forms.ValidationError(_("Code must be [a-zA-Z0-9]"))
        if not 1 <= len(input_code) <= 32:
            raise forms.ValidationError(_("Code must be between 1 and 32 characters"))
        return self.cleaned_data


class VPNUserInline(admin.StackedInline):

# Path: lambdainst/models.py
# class VPNUser(models.Model):
#     class Meta:
#         verbose_name = _("VPN User")
#         verbose_name_plural = _("VPN Users")
# 
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
#     notes = models.TextField(blank=True)
# 
#     expiration = models.DateTimeField(blank=True, null=True)
#     last_expiry_notice = models.DateTimeField(blank=True, null=True)
#     notify_expiration = models.BooleanField(default=True)
# 
#     trial_periods_given = models.IntegerField(default=0)
# 
#     last_vpn_auth = models.DateTimeField(blank=True, null=True)
# 
#     referrer = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL,
#                                  related_name='referrals')
#     referrer_used = models.BooleanField(default=False)
#     campaign = models.CharField(blank=True, null=True, max_length=64)
# 
#     @property
#     def is_paid(self):
#         if self.get_subscription():
#             return True
#         if not self.expiration:
#             return False
#         return self.expiration > timezone.now()
# 
#     @property
#     def time_left(self):
#         return timezone.now() - self.expiration
# 
#     def add_paid_time(self, time):
#         now = timezone.now()
#         if not self.expiration or self.expiration < now:
#             self.expiration = now
#         self.expiration += time
# 
#         # Propagate update to core
#         if core.VPN_AUTH_STORAGE == 'core':
#             core.update_user_expiration(self.user)
# 
#     def give_trial_period(self):
#         self.add_paid_time(get_trial_period_duration())
#         self.trial_periods_given += 1
# 
#     @property
#     def can_have_trial(self):
#         if self.trial_periods_given >= site_config.TRIAL_PERIOD_MAX:
#             return False
#         if self.user.payment_set.filter(status='confirmed').count() > 0:
#             return False
#         return True
# 
#     @property
#     def remaining_trial_periods(self):
#         return site_config.TRIAL_PERIOD_MAX - self.trial_periods_given
# 
#     def on_payment_confirmed(self, payment):
#         if self.referrer and not self.referrer_used:
#             self.referrer.vpnuser.add_paid_time(timedelta(days=14))
#             self.referrer.vpnuser.save()
#             self.referrer_used = True
# 
#     def get_subscription(self, include_unconfirmed=False):
#         """ Tries to get the active (and most recent) Subscription """
#         s = Subscription.objects.filter(user=self.user, status='active') \
#                                 .order_by('-id') \
#                                 .first()
#         if s is not None or include_unconfirmed is False:
#             return s
#         s = Subscription.objects.filter(user=self.user, status='unconfirmed') \
#                                 .order_by('-id') \
#                                 .first()
#         return s
# 
#     def __str__(self):
#         return self.user.username
# 
# class GiftCode(models.Model):
#     class Meta:
#         verbose_name = _("Gift Code")
#         verbose_name_plural = _("Gift Codes")
# 
#     code = models.CharField(max_length=32, default=random_gift_code)
#     time = models.DurationField(default=timedelta(days=30))
#     created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
#     created_by = models.ForeignKey(User, related_name='created_giftcode_set',
#                                    on_delete=models.CASCADE, null=True, blank=True)
#     single_use = models.BooleanField(default=True)
#     free_only = models.BooleanField(default=True)
#     available = models.BooleanField(default=True)
#     comment = models.TextField(blank=True)
#     users = models.ManyToManyField(User, through='GiftCodeUser')
# 
#     def use_on(self, user):
#         if not self.available:
#             return False
#         if self.free_only and user.vpnuser.is_paid:
#             return False
# 
#         link = GiftCodeUser(user=user, code=self)
#         link.save()
# 
#         user.vpnuser.add_paid_time(self.time)
#         user.vpnuser.save()
# 
#         if self.single_use:
#             self.available = False
# 
#         self.save()
# 
#         return True
# 
#     @property
#     def comment_head(self):
#         head = self.comment.split('\n', 1)[0]
#         if len(head) > 80:
#             head = head[:80] + "..."
#         return head
# 
#     def __str__(self):
#         return self.code
# 
# class GiftCodeUser(models.Model):
#     class Meta:
#         verbose_name = _("Gift Code User")
#         verbose_name_plural = _("Gift Code Users")
# 
#     user = models.ForeignKey(User)
#     code = models.ForeignKey(GiftCode)
#     date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
# 
#     def __str__(self):
#         return "%s (%s)" % (self.user.username, self.code.code)


# Path: lambdainst/admin.py
import string
from django.shortcuts import resolve_url
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from lambdainst.models import VPNUser, GiftCode, GiftCodeUser
from . import core




def make_user_link(user):
    change_url = resolve_url('admin:auth_user_change', user.id)
    return '<a href="%s">%s</a>' % (change_url, user.username)


class GiftCodeAdminForm(forms.ModelForm):
    def clean(self):
        input_code = self.cleaned_data.get('code', '')
        code_charset = string.ascii_letters + string.digits
        if any(c not in code_charset for c in input_code):
            raise forms.ValidationError(_("Code must be [a-zA-Z0-9]"))
        if not 1 <= len(input_code) <= 32:
            raise forms.ValidationError(_("Code must be between 1 and 32 characters"))
        return self.cleaned_data


class VPNUserInline(admin.StackedInline):

    model = VPNUser