# Generated by Django 6.0 on 2025-12-31 23:09

import archivebox.base_models.models
import django.db.models.deletion
import django.utils.timezone
import uuid
from django.conf import settings
from django.db import migrations, models, connection


def copy_old_fields_to_new(apps, schema_editor):
    """Copy data from old field names to new field names after AddField operations."""
    cursor = connection.cursor()

    # Check if old fields still exist
    cursor.execute("PRAGMA table_info(core_archiveresult)")
    cols = {row[1] for row in cursor.fetchall()}

    if 'extractor' in cols and 'plugin' in cols:
        # Copy extractor -> plugin
        cursor.execute("UPDATE core_archiveresult SET plugin = COALESCE(extractor, '') WHERE plugin = '' OR plugin IS NULL")

    if 'output' in cols and 'output_str' in cols:
        # Copy output -> output_str
        cursor.execute("UPDATE core_archiveresult SET output_str = COALESCE(output, '') WHERE output_str = '' OR output_str IS NULL")

    # Copy timestamps to new timestamp fields if they don't have values yet
    if 'start_ts' in cols and 'created_at' in cols:
        cursor.execute("UPDATE core_archiveresult SET created_at = COALESCE(start_ts, CURRENT_TIMESTAMP) WHERE created_at IS NULL OR created_at = ''")

    if 'end_ts' in cols and 'modified_at' in cols:
        cursor.execute("UPDATE core_archiveresult SET modified_at = COALESCE(end_ts, start_ts, CURRENT_TIMESTAMP) WHERE modified_at IS NULL OR modified_at = ''")

    # NOTE: Snapshot timestamps (added→bookmarked_at, updated→modified_at) were already
    # transformed by migration 0023, so we don't need to copy them here.

    # Debug: Check Snapshot timestamps at end of RunPython
    cursor.execute("SELECT id, bookmarked_at, modified_at FROM core_snapshot LIMIT 2")
    snap_after = cursor.fetchall()
    print(f'DEBUG 0025: Snapshot timestamps at END of RunPython: {snap_after}')


class Migration(migrations.Migration):

    dependencies = [
        ('core', '0024_assign_default_crawl'),
        ('crawls', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='archiveresult',
            options={'verbose_name': 'Archive Result', 'verbose_name_plural': 'Archive Results Log'},
        ),
        migrations.AlterModelOptions(
            name='snapshot',
            options={'verbose_name': 'Snapshot', 'verbose_name_plural': 'Snapshots'},
        ),
        # NOTE: RemoveField for cmd, cmd_version, pwd moved to migration 0027
        # to allow data migration to Process records first
        migrations.AddField(
            model_name='archiveresult',
            name='config',
            field=models.JSONField(blank=True, default=dict, null=True),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='created_at',
            field=models.DateTimeField(db_index=True, default=django.utils.timezone.now),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='hook_name',
            field=models.CharField(blank=True, db_index=True, default='', help_text='Full filename of the hook that executed (e.g., on_Snapshot__50_wget.py)', max_length=255),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='modified_at',
            field=models.DateTimeField(auto_now=True),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='notes',
            field=models.TextField(blank=True, default=''),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='num_uses_failed',
            field=models.PositiveIntegerField(default=0),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='num_uses_succeeded',
            field=models.PositiveIntegerField(default=0),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='output_files',
            field=models.JSONField(default=dict, help_text='Dict of {relative_path: {metadata}}'),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='output_json',
            field=models.JSONField(blank=True, default=None, help_text='Structured metadata (headers, redirects, etc.)', null=True),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='output_mimetypes',
            field=models.CharField(blank=True, default='', help_text='CSV of mimetypes sorted by size', max_length=512),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='output_size',
            field=models.BigIntegerField(default=0, help_text='Total bytes of all output files'),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='output_str',
            field=models.TextField(blank=True, default='', help_text='Human-readable output summary'),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='plugin',
            field=models.CharField(db_index=True, default='', max_length=32),
        ),
        migrations.AddField(
            model_name='archiveresult',
            name='retry_at',
            field=models.DateTimeField(blank=True, db_index=True, default=django.utils.timezone.now, null=True),
        ),
        # NOTE: bookmarked_at and created_at already added by migration 0023
        migrations.AddField(
            model_name='snapshot',
            name='config',
            field=models.JSONField(default=dict),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='current_step',
            field=models.PositiveSmallIntegerField(db_index=True, default=0, help_text='Current hook step being executed (0-9). Used for sequential hook execution.'),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='depth',
            field=models.PositiveSmallIntegerField(db_index=True, default=0),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='downloaded_at',
            field=models.DateTimeField(blank=True, db_index=True, default=None, editable=False, null=True),
        ),
        # NOTE: fs_version already added by migration 0023 with default='0.8.0'
        # NOTE: modified_at already added by migration 0023
        migrations.AddField(
            model_name='snapshot',
            name='notes',
            field=models.TextField(blank=True, default=''),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='num_uses_failed',
            field=models.PositiveIntegerField(default=0),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='num_uses_succeeded',
            field=models.PositiveIntegerField(default=0),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='parent_snapshot',
            field=models.ForeignKey(blank=True, help_text='Parent snapshot that discovered this URL (for recursive crawling)', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_snapshots', to='core.snapshot'),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='retry_at',
            field=models.DateTimeField(blank=True, db_index=True, default=django.utils.timezone.now, null=True),
        ),
        migrations.AddField(
            model_name='snapshot',
            name='status',
            field=models.CharField(choices=[('queued', 'Queued'), ('started', 'Started'), ('sealed', 'Sealed')], db_index=True, default='queued', max_length=15),
        ),
        migrations.AddField(
            model_name='tag',
            name='created_at',
            field=models.DateTimeField(db_index=True, default=django.utils.timezone.now, null=True),
        ),
        migrations.AddField(
            model_name='tag',
            name='created_by',
            field=models.ForeignKey(default=archivebox.base_models.models.get_or_create_system_user_pk, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tag_set', to=settings.AUTH_USER_MODEL),
        ),
        migrations.AddField(
            model_name='tag',
            name='modified_at',
            field=models.DateTimeField(auto_now=True),
        ),
        # Copy data from old field names to new field names after AddField operations
        migrations.RunPython(
            copy_old_fields_to_new,
            reverse_code=migrations.RunPython.noop,
        ),
        # Now remove the old ArchiveResult fields after data has been copied
        migrations.RemoveField(
            model_name='archiveresult',
            name='extractor',
        ),
        migrations.RemoveField(
            model_name='archiveresult',
            name='output',
        ),
        # NOTE: Snapshot's added/updated were already removed by migration 0023
        migrations.AlterField(
            model_name='archiveresult',
            name='end_ts',
            field=models.DateTimeField(blank=True, default=None, null=True),
        ),
        migrations.AlterField(
            model_name='archiveresult',
            name='id',
            field=models.AutoField(editable=False, primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='archiveresult',
            name='start_ts',
            field=models.DateTimeField(blank=True, default=None, null=True),
        ),
        migrations.AlterField(
            model_name='archiveresult',
            name='status',
            field=models.CharField(choices=[('queued', 'Queued'), ('started', 'Started'), ('backoff', 'Waiting to retry'), ('succeeded', 'Succeeded'), ('failed', 'Failed'), ('skipped', 'Skipped')], db_index=True, default='queued', max_length=15),
        ),
        migrations.AlterField(
            model_name='archiveresult',
            name='uuid',
            field=models.UUIDField(blank=True, db_index=True, default=uuid.uuid7, null=True),
        ),
        migrations.AlterField(
            model_name='snapshot',
            name='crawl',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snapshot_set', to='crawls.crawl'),
        ),
        migrations.AlterField(
            model_name='snapshot',
            name='id',
            field=models.UUIDField(default=uuid.uuid7, editable=False, primary_key=True, serialize=False, unique=True),
        ),
        migrations.AlterField(
            model_name='snapshot',
            name='tags',
            field=models.ManyToManyField(blank=True, related_name='snapshot_set', through='core.SnapshotTag', through_fields=('snapshot', 'tag'), to='core.tag'),
        ),
        migrations.AlterField(
            model_name='snapshot',
            name='timestamp',
            field=models.CharField(db_index=True, editable=False, max_length=32, unique=True),
        ),
        migrations.AlterField(
            model_name='snapshot',
            name='url',
            field=models.URLField(db_index=True),
        ),
        migrations.AlterField(
            model_name='tag',
            name='slug',
            field=models.SlugField(editable=False, max_length=100, unique=True),
        ),
        migrations.AddConstraint(
            model_name='snapshot',
            constraint=models.UniqueConstraint(fields=('url', 'crawl'), name='unique_url_per_crawl'),
        ),
        migrations.AddConstraint(
            model_name='snapshot',
            constraint=models.UniqueConstraint(fields=('timestamp',), name='unique_timestamp'),
        ),
    ]
