"""
Test the actual migration script (migrate_from_akumuli.py).

This test runs the migration script as a subprocess to ensure it executes correctly.
Note: Full data verification is done in test_migration.py with direct API calls.
"""
from __future__ import annotations

import anyio
import os
import pytest
import sqlite3
import subprocess
import sys
import tempfile

try:
    from asyncakumuli import DS, Entry
    from asyncakumuli import connect as akumuli_connect
    from asyncakumuli.mock import AkumuliTester
    HAS_AKUMULI = True
except ImportError:
    HAS_AKUMULI = False

from asyncvictoria.mock import VictoriaTester


@pytest.mark.skipif(not HAS_AKUMULI, reason="asyncakumuli package not installed")
async def test_migration_script_with_series_arg(free_tcp_port_factory):
    """Test the migration script using --series argument."""

    test_series = "migration_test_A"
    test_tags = {"env": "test", "host": "localhost"}
    test_values = [
        (1500000000, 100),
        (1500000060, 200),
        (1500000120, 300),
    ]

    akumuli_tcp_port = free_tcp_port_factory()
    akumuli_http_port = free_tcp_port_factory()
    victoria_tcp_port = free_tcp_port_factory()
    victoria_http_port = free_tcp_port_factory()

    # Start Akumuli and write test data
    print("\n=== Starting Akumuli ===")
    async with AkumuliTester(akumuli_tcp_port, akumuli_http_port).run() as akumuli:
        # Write test data
        for timestamp, value in test_values:
            e = Entry(
                series=test_series,
                time=timestamp,
                value=value,
                tags=test_tags,
                mode=DS.gauge,
            )
            await akumuli.put(e)

        await akumuli.flush()
        await anyio.sleep(0.5)

        # Start VictoriaMetrics
        print("=== Starting VictoriaMetrics ===")
        async with VictoriaTester(victoria_tcp_port, victoria_http_port).run() as victoria:
            # Run the migration script
            print("=== Running migration script ===")
            script_path = os.path.join(os.path.dirname(__file__), "..", "migrate_from_akumuli.py")

            # Build series spec with tags
            series_spec = f"{test_series}{{env={test_tags['env']},host={test_tags['host']}}}"

            result = subprocess.run(
                [
                    sys.executable,
                    script_path,
                    "--akumuli-http", f"http://localhost:{akumuli_http_port}",
                    "--victoria-tcp", f"localhost:{victoria_tcp_port}",
                    "--victoria-http", f"http://localhost:{victoria_http_port}",
                    "--series", series_spec,
                    "--start-time", "1490000000",
                    "--end-time", "1510000000",
                ],
                check=False, capture_output=True,
                text=True,
            )

            print("Migration script output:")
            print(result.stdout)
            if result.stderr:
                print("Migration script stderr:")
                print(result.stderr)

            assert result.returncode == 0, f"Migration script failed: {result.stderr}"
            assert f"Migrated {len(test_values)} points total" in result.stdout, \
                "Expected migration confirmation in output"

            print("✓ Migration script executed successfully!")


@pytest.mark.skipif(not HAS_AKUMULI, reason="asyncakumuli package not installed")
async def test_migration_script_with_db_autodiscovery(free_tcp_port_factory):
    """Test the migration script using --akumuli-db for auto-discovery."""

    test_series = ["auto_test_A", "auto_test_B"]
    test_tags = {"env": "prod"}
    test_data = {
        "auto_test_A": [(1500000000, 111), (1500000060, 222)],
        "auto_test_B": [(1500000000, 333), (1500000060, 444)],
    }

    akumuli_tcp_port = free_tcp_port_factory()
    akumuli_http_port = free_tcp_port_factory()
    victoria_tcp_port = free_tcp_port_factory()
    victoria_http_port = free_tcp_port_factory()

    # Create a temporary SQLite database for Akumuli series
    with tempfile.NamedTemporaryFile(mode="w", suffix=".akumuli", delete=False) as f:
        db_path = f.name

    try:
        # Create test database
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()
        cursor.execute("CREATE TABLE akumuli_series (series_id TEXT)")
        for series in test_series:
            cursor.execute("INSERT INTO akumuli_series VALUES (?)", (series,))
        conn.commit()
        conn.close()

        # Start Akumuli and write test data
        print("\n=== Starting Akumuli ===")
        async with AkumuliTester(akumuli_tcp_port, akumuli_http_port).run() as akumuli:
            # Write test data
            for series, values in test_data.items():
                for timestamp, value in values:
                    e = Entry(
                        series=series,
                        time=timestamp,
                        value=value,
                        tags=test_tags,
                        mode=DS.gauge,
                    )
                    await akumuli.put(e)

            await akumuli.flush()
            await anyio.sleep(0.5)

            # Start VictoriaMetrics
            print("=== Starting VictoriaMetrics ===")
            async with VictoriaTester(victoria_tcp_port, victoria_http_port).run() as victoria:
                # Run the migration script with --akumuli-db
                print("=== Running migration script with auto-discovery ===")
                script_path = os.path.join(os.path.dirname(__file__), "..", "migrate_from_akumuli.py")

                result = subprocess.run(
                    [
                        sys.executable,
                        script_path,
                        "--akumuli-http", f"http://localhost:{akumuli_http_port}",
                        "--akumuli-db", db_path,
                        "--victoria-tcp", f"localhost:{victoria_tcp_port}",
                        "--victoria-http", f"http://localhost:{victoria_http_port}",
                        "--start-time", "1490000000",
                        "--end-time", "1510000000",
                    ],
                    check=False, capture_output=True,
                    text=True,
                )

                print("Migration script output:")
                print(result.stdout)
                if result.stderr:
                    print("Migration script stderr:")
                    print(result.stderr)

                assert result.returncode == 0, f"Migration script failed: {result.stderr}"
                assert "auto_test_A" in result.stdout, "Should mention auto_test_A in output"
                assert "auto_test_B" in result.stdout, "Should mention auto_test_B in output"
                assert "Found 2 series to migrate" in result.stdout, "Should show series discovery"

                # Verify migrations reported
                for series in test_series:
                    assert f"Migrating series: {series}" in result.stdout, \
                        f"Should report migration of {series}"

                print("✓ Auto-discovery migration test passed!")

    finally:
        os.unlink(db_path)


@pytest.mark.skipif(not HAS_AKUMULI, reason="asyncakumuli package not installed")
async def test_migration_script_with_illegal_names(free_tcp_port_factory):
    """Test the migration script with illegal Prometheus names."""

    # Use illegal characters in series and tag names
    test_series = "test-metric.with-illegal.chars"
    test_tags = {"host-name": "server1", "data.center": "dc1"}
    test_values = [
        (1500000000, 555),
        (1500000060, 666),
    ]

    akumuli_tcp_port = free_tcp_port_factory()
    akumuli_http_port = free_tcp_port_factory()
    victoria_tcp_port = free_tcp_port_factory()
    victoria_http_port = free_tcp_port_factory()

    # Start Akumuli and write test data
    print("\n=== Starting Akumuli with illegal names ===")
    async with AkumuliTester(akumuli_tcp_port, akumuli_http_port).run() as akumuli:
        # Write test data with illegal characters
        for timestamp, value in test_values:
            e = Entry(
                series=test_series,
                time=timestamp,
                value=value,
                tags=test_tags,
                mode=DS.gauge,
            )
            await akumuli.put(e)

        await akumuli.flush()
        await anyio.sleep(0.5)

        # Start VictoriaMetrics
        print("=== Starting VictoriaMetrics ===")
        async with VictoriaTester(victoria_tcp_port, victoria_http_port).run() as victoria:
            # Run the migration script
            print("=== Running migration script ===")
            script_path = os.path.join(os.path.dirname(__file__), "..", "migrate_from_akumuli.py")

            # Build series spec with illegal characters
            series_spec = f"{test_series}{{host-name={test_tags['host-name']},data.center={test_tags['data.center']}}}"

            result = subprocess.run(
                [
                    sys.executable,
                    script_path,
                    "--akumuli-http", f"http://localhost:{akumuli_http_port}",
                    "--victoria-tcp", f"localhost:{victoria_tcp_port}",
                    "--victoria-http", f"http://localhost:{victoria_http_port}",
                    "--series", series_spec,
                    "--start-time", "1490000000",
                    "--end-time", "1510000000",
                ],
                check=False, capture_output=True,
                text=True,
            )

            print("Migration script output:")
            print(result.stdout)
            if result.stderr:
                print("Migration script stderr:")
                print(result.stderr)

            assert result.returncode == 0, f"Migration script failed: {result.stderr}"
            assert f"Migrated {len(test_values)} points total" in result.stdout, \
                "Expected migration confirmation in output"

            print("✓ Illegal names migration script executed successfully!")
            print("   (Name sanitization verified in test_sanitization.py)")
