from django.core.management.base import BaseCommand
from users.models import User, School, Adherent, Club
from machines.models import Domain, Machine
from reversion.models import Revision
from django.db.models import F, Value
from django.db.models import Q
from django.db.models.functions import Concat

from re2o.login import hashNT, makeSecret

import os, random, string
from random import randint


class Command(BaseCommand):
    help = "Anonymise the data in the database in order to use them on critical servers (dev, personal...). Every information will be overwritten using non-personal information. This script must follow any modification of the database.\nOptional argument: {id|id|id|...} to exclude users from anonymisation."

    def add_arguments(self, parser):
        parser.add_argument("user_id", nargs="+", type=int, help="User ID")

    def handle(self, *args, **kwargs):
        users_ids = kwargs["user_id"]
        for user_id in users_ids:
            self.stdout.write(
                "User: {} will not be anonymised.".format(
                    User.objects.filter(id=user_id).get().name
                )
            )

        self.stdout.write(
            self.style.WARNING(
                "\nDISCLAIMER\nThis function will make your database unusable for production. Are you sure you want to run this? (doit): "
            )
        )
        if input() == "doit":

            total = Adherent.objects.count()
            self.stdout.write("Starting anonymizing the {} users data.".format(total))

            u = User.objects.filter(~Q(id__in=users_ids))
            a = Adherent.objects.filter(~Q(id__in=users_ids))
            c = Club.objects.filter(~Q(id__in=users_ids))
            d = Domain.objects.all()
            m = Machine.objects.filter(~Q(user_id__in=users_ids))

            self.stdout.write("Deletion of the school...")
            # Create a fake School to put everyone in it.
            ecole = School(name="Ninja School")
            ecole.save()
            u.update(school=ecole)
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write("Deletion of rooms...")
            a.update(room=None)
            c.update(room=None)
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write("Deletion of email addresses...")
            u.update(
                email="example@example.org",
                local_email_redirect=False,
                local_email_enabled=False,
            )
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write(
                "Deletion of first names, surnames, usernames, telephone numbers, comments..."
            )
            a.update(name=Concat(Value("First name of "), "id"))
            self.stdout.write(self.style.SUCCESS("Done for first names..."))

            a.update(surname=Concat(Value("Surname of "), "id"))
            self.stdout.write(self.style.SUCCESS("Done for surnames..."))

            u.update(pseudo=F("id"))
            self.stdout.write(self.style.SUCCESS("Done for usernames..."))

            a.update(telephone=Concat(Value("Telephone number of "), "id"))
            self.stdout.write(self.style.SUCCESS("Done for telephone numbers..."))

            a.update(comment=Concat(Value("Comment of "), "id"))
            self.stdout.write(self.style.SUCCESS("Done for comments..."))

            self.stdout.write("Renaming of machines...")
            m.update(
                name=Concat(Value("Machine "), F("id"), Value(" of "), F("user_id"))
            )
            d.update(name=Concat(Value("Domain id "), F("id")))
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write("Unification of the password...")
            # Define the password
            chars = string.ascii_letters + string.digits + "!@#$%^&*()"
            taille = 20
            random.seed = os.urandom(1024)
            password = ""
            for i in range(taille):
                password += random.choice(chars)

            self.stdout.write(
                self.style.HTTP_NOT_MODIFIED(
                    "The password will be: {}.".format(password)
                )
            )

            u.update(pwd_ntlm=hashNT(password))
            u.update(password=makeSecret(password))
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write("Deletion of the history (this may take some time)...")
            Revision.objects.all().delete()
            self.stdout.write(self.style.SUCCESS("Done..."))

            self.stdout.write("Data anonymised!")

        else:
            self.stdout.write("Anonymisation aborted!")