# Generated by Django 3.2.12 on 2022-04-01 20:07
from __future__ import annotations

from typing import TYPE_CHECKING

import django.contrib.auth.models
from django.db import migrations

import integreat_cms.cms.models.users.user

if TYPE_CHECKING:
    from django.apps.registry import Apps
    from django.db.backends.base.schema import BaseDatabaseSchemaEditor


# pylint: disable=unused-argument
def make_user_email_field_unique(
    apps: Apps, schema_editor: BaseDatabaseSchemaEditor
) -> None:
    """
    Make sure that the email field of users is unique

    :param apps: The configuration of installed applications
    :param schema_editor: The database abstraction layer that creates actual SQL code
    """
    # "Import" historic version of user model
    User = apps.get_model("cms.User")
    # Get list of all email addresses
    emails = list(User.objects.values_list("email", flat=True))
    # Get list of emails that are used by more than one user
    duplicate_emails = {email for email in emails if emails.count(email) > 1}
    # Get all users with duplicated emails
    users = User.objects.filter(email__in=duplicate_emails)
    for user in users:
        old_email = user.email
        email_username, domain = old_email.split("@")
        # Make email unique by adding username tag (not supported by all email providers, but better than nothing)
        user.email = f"{email_username}+{user.username}@{domain}"
        # Set user inactive to make sure new email is reviewed/changed before password reset is possible
        user.is_active = False
        user.save()
        print(
            f"\n    ↳ Email address of user {user.username} was changed from {old_email} to {user.email} ✔",
            end="",
        )


class Migration(migrations.Migration):
    """
    Make the email field of users unique
    """

    dependencies = [
        ("cms", "0014_language_content_not_available_translations"),
    ]

    operations = [
        # Revert to the default user manager because prefetching causes problems
        migrations.AlterModelManagers(
            name="user",
            managers=[
                ("objects", django.contrib.auth.models.UserManager()),
            ],
        ),
        # Ensure that existing email addresses are unique
        migrations.RunPython(make_user_email_field_unique, migrations.RunPython.noop),
        # Restore the custom user manager
        migrations.AlterModelManagers(
            name="user",
            managers=[
                ("objects", integreat_cms.cms.models.users.user.CustomUserManager()),
            ],
        ),
        # Make email field unique
        migrations.AlterUniqueTogether(
            name="user",
            unique_together={("email",)},
        ),
    ]
