# Generated by Django 4.2.19 on 2025-09-19 01:16

import ipaddress

from django.conf import settings
from django.db import migrations


def _default_domain(apps):
    # 1) Sites Framework
    try:
        if "django.contrib.sites" in getattr(settings, "INSTALLED_APPS", []):
            Site = apps.get_model("sites", "Site")
            site_id = getattr(settings, "SITE_ID", None)
            if site_id:
                site = Site.objects.filter(pk=site_id).only("domain").first()
                if site and site.domain:
                    return site.domain
    except Exception:
        pass
    # 2) ALLOWED_HOSTS
    hosts = getattr(settings, "ALLOWED_HOSTS", []) or []
    for h in hosts:
        if h and h != "*":
            return h
    # 3) fallback
    return "localhost"


def _parse_host_port(raw):
    if raw is None:
        return None, None
    s = str(raw).strip()
    if not s:
        return None, None
    # [ipv6]:port
    if s.startswith("["):
        end = s.find("]")
        if end != -1:
            host = s[1:end]
            port = None
            rest = s[end + 1 :]
            if rest.startswith(":"):
                p = rest[1:]
                if p.isdigit():
                    port = int(p)
            return host, port
    # host:port
    host, port = s, None
    if s.count(":") == 1:
        h, p = s.rsplit(":", 1)
        if p.isdigit():
            host, port = h, int(p)
    return host, port


def _is_ip(value):
    try:
        ipaddress.ip_address(value)
        return True
    except Exception:
        return False


def backfill_server_host_and_port(apps, schema_editor):
    ServerLog = apps.get_model("django_logbox", "ServerLog")
    default_domain = _default_domain(apps)
    local_set = {"127.0.0.1", "::1"}
    qs = ServerLog.objects.filter(server_host__isnull=True).order_by("pk")
    last_pk = 0
    batch_size = 10000
    while True:
        rows = list(
            qs.filter(pk__gt=last_pk).values("pk", "server_ip", "server_port")[
                :batch_size
            ]
        )
        if not rows:
            break
        for row in rows:
            pk = row["pk"]
            raw = row["server_ip"]
            host, port = _parse_host_port(raw)
            domain = None
            if host:
                host = host.strip().rstrip(".")
                if _is_ip(host):
                    domain = "localhost" if host in local_set else host
                else:
                    domain = host.lower()
            if not domain:
                domain = default_domain
            update_kwargs = {"server_host": domain}
            if (
                row.get("server_port") is None
                and isinstance(port, int)
                and 1 <= port <= 65535
            ):
                update_kwargs["server_port"] = port
            ServerLog.objects.filter(pk=pk, server_host__isnull=True).update(
                **update_kwargs
            )
        last_pk = rows[-1]["pk"]


class Migration(migrations.Migration):
    dependencies = [
        ("django_logbox", "0008_serverlog_server_host_serverlog_server_port"),
    ]
    operations = [
        migrations.RunPython(
            backfill_server_host_and_port, reverse_code=migrations.RunPython.noop
        ),
    ]
