# Generated by Django 4.2.4 on 2023-08-09 16:54

from datetime import timedelta

from django.conf import settings
from django.db import migrations, models, transaction
from django.utils import timezone
from loguru import logger
from tqdm import tqdm

from takahe.models import Config as TakaheConfig
from takahe.models import Domain as TakaheDomain
from takahe.models import Identity as TakaheIdentity
from takahe.models import User as TakaheUser

domain = settings.SITE_INFO["site_domain"]
name = settings.SITE_INFO["site_name"]
service_domain = settings.SITE_INFO.get("site_service_domain")


def init_domain(apps, schema_editor):
    User = apps.get_model("users", "User")
    if not User.objects.exists():
        logger.warning(
            "No users found, skip domain migration (if you are running initial migration for new site, pls ignore this)"
        )
        return
    logger.info(f"Creating takahe domain {domain}")
    TakaheDomain.objects.update_or_create(
        domain=domain,
        defaults={
            "local": True,
            "service_domain": service_domain,
            "notes": "NeoDB",
            "nodeinfo": {},
            "state": "updated",
        },
    )
    TakaheConfig.objects.update_or_create(
        key="public_timeline",
        user=None,
        identity=None,
        domain=None,
        defaults={"json": False},
    )
    TakaheConfig.objects.update_or_create(
        key="site_name",
        user=None,
        identity=None,
        domain=None,
        defaults={"json": name},
    )
    TakaheConfig.objects.update_or_create(
        key="site_name",
        user=None,
        identity=None,
        domain_id=domain,
        defaults={"json": name},
    )


def init_identity(apps, schema_editor):
    User = apps.get_model("users", "User")
    if not User.objects.exists():
        logger.warning(
            "No users found, skip identity migration (if you are running initial migration for new site, pls ignore this)"
        )
        return
    APIdentity = apps.get_model("users", "APIdentity")
    tdomain = TakaheDomain.objects.filter(domain=domain).first()
    if User.objects.filter(username__isnull=True).exists():
        raise ValueError("null username detected, aborting migration")
    if TakaheUser.objects.exists():
        raise ValueError("existing Takahe users detected, aborting migration")
    if TakaheIdentity.objects.exists():
        raise ValueError("existing Takahe identities detected, aborting migration")
    if APIdentity.objects.exists():
        raise ValueError("existing APIdentity data detected, aborting migration")
    logger.info(f"Creating takahe users/identities")
    for user in tqdm(User.objects.all()):
        username = user.username
        handler = "@" + username
        identity = APIdentity.objects.create(
            pk=user.pk,
            user=user,
            local=True,
            username=username,
            domain_name=domain,
            deleted=(
                None
                if user.is_active
                else user.mastodon_last_reachable + timedelta(days=90)
            ),
        )
        takahe_user = TakaheUser.objects.create(
            pk=user.pk, email=handler, admin=user.is_superuser, password=user.password
        )
        takahe_identity = TakaheIdentity.objects.create(
            pk=user.pk,
            actor_uri=f"https://{service_domain or domain}/@{username}@{domain}/",
            profile_uri=f"https://{service_domain or domain}/users/{username}/",
            username=username,
            domain=tdomain,
            name=username,
            local=True,
            discoverable=True,
            state="updated",
            state_next_attempt=timezone.now() + timedelta(days=365 * 99),
        )
        takahe_identity.generate_keypair()
        takahe_identity.ensure_uris()
        takahe_user.identities.add(takahe_identity)


class Migration(migrations.Migration):
    dependencies = [
        ("users", "0012_apidentity"),
    ]

    operations = [
        migrations.RunPython(init_domain),
        migrations.RunPython(init_identity),
    ]
