#!/usr/bin/env python3
"""Test progress bar during file transfer."""

import os
import signal
import subprocess
import sys
import time

TEST_DIR = "/tmp/peerdrop_progress_test"
SOCK_SENDER = os.path.join(TEST_DIR, "sender.sock")
SOCK_RECEIVER = os.path.join(TEST_DIR, "receiver.sock")
TEST_FILE = os.path.join(TEST_DIR, "test_100mb.bin")
DOWNLOAD_DIR = os.path.join(TEST_DIR, "downloads")

os.makedirs(TEST_DIR, exist_ok=True)
os.makedirs(DOWNLOAD_DIR, exist_ok=True)


def kill_daemons():
    for sock in [SOCK_SENDER, SOCK_RECEIVER]:
        pid_file = sock.replace(".sock", ".pid")
        try:
            if os.path.exists(pid_file):
                with open(pid_file) as f:
                    pid = int(f.read().strip())
                os.kill(pid, signal.SIGTERM)
                time.sleep(0.5)
                try:
                    os.kill(pid, signal.SIGKILL)
                except ProcessLookupError:
                    pass
            for f in [sock, pid_file]:
                if os.path.exists(f):
                    os.unlink(f)
        except Exception:
            pass


def wait_for_socket(path, timeout=15):
    for _ in range(timeout):
        time.sleep(1)
        if os.path.exists(path):
            return True
    return False


def main():
    print("=" * 60)
    print("Progress Bar Test")
    print("=" * 60)

    kill_daemons()

    # Create 100MB test file (enough to see progress)
    file_size = 100 * 1024 * 1024
    if not os.path.exists(TEST_FILE) or os.path.getsize(TEST_FILE) != file_size:
        print(f"\nCreating 100MB test file...")
        chunk = os.urandom(1024 * 1024)
        with open(TEST_FILE, "wb") as f:
            for _ in range(100):
                f.write(chunk)
        print(f"  Created: {os.path.getsize(TEST_FILE)} bytes")

    # Start daemons
    print("\nStarting daemons...")
    receiver_proc = subprocess.Popen(
        [sys.executable, "-m", "peerdrop.interfaces.cli.app",
         "--sock", SOCK_RECEIVER, "daemon", "start",
         "--port", "4003", "--download-dir", DOWNLOAD_DIR],
        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
    )
    if not wait_for_socket(SOCK_RECEIVER):
        print("  ERROR: Receiver failed to start")
        return 1
    print("  Receiver ready")

    sender_proc = subprocess.Popen(
        [sys.executable, "-m", "peerdrop.interfaces.cli.app",
         "--sock", SOCK_SENDER, "daemon", "start", "--port", "4004"],
        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
    )
    if not wait_for_socket(SOCK_SENDER):
        print("  ERROR: Sender failed to start")
        return 1
    print("  Sender ready")

    # Get peer IDs and connect
    sys.path.insert(0, os.getcwd())
    from peerdrop.interfaces.client import PeerDropClient

    sender_client = PeerDropClient(SOCK_SENDER)
    sender_client.connect()
    sender_id = sender_client.get_identity().get("data", {}).get("peer_id", "")

    receiver_client = PeerDropClient(SOCK_RECEIVER)
    receiver_client.connect()
    receiver_id = receiver_client.get_identity().get("data", {}).get("peer_id", "")
    receiver_addrs = receiver_client.get_identity().get("data", {}).get("addrs", [])

    # Connect sender to receiver
    for addr in receiver_addrs:
        if "/ip4/" in addr and "/ip6/" not in addr:
            try:
                sender_client.connect_peer(addr)
                print(f"  Connected sender to receiver")
                break
            except Exception:
                pass

    time.sleep(1)

    # Run the CLI send command and capture output
    print(f"\nRunning: peerdrop send {TEST_FILE} --to {receiver_id[:16]}...")
    print("CLI output:")
    print("-" * 40)

    result = subprocess.run(
        [sys.executable, "-m", "peerdrop.interfaces.cli.app",
         "--sock", SOCK_SENDER, "send",
         TEST_FILE, "--to", receiver_id],
        capture_output=True, text=True,
        timeout=120,
    )

    print(result.stdout)
    if result.stderr:
        print(f"STDERR: {result.stderr[:500]}")

    print("-" * 40)

    # Check transfer status
    transfers = sender_client.list_transfers()
    if transfers:
        t = transfers[-1]
        print(f"\nFinal status: {t.get('status')}")
        print(f"Progress: {t.get('progress', 0) * 100:.1f}%")

    # Verify file
    received = os.path.join(DOWNLOAD_DIR, "test_100mb.bin")
    if os.path.exists(received):
        print(f"File received: {os.path.getsize(received)} bytes")
        if os.path.getsize(received) == file_size:
            print("SIZE MATCH: YES")
        else:
            print("SIZE MATCH: NO")

    # Check if progress bar was shown (look for [=== pattern in output)
    if "[=" in result.stdout:
        print("\nPROGRESS BAR: VISIBLE")
    else:
        print("\nPROGRESS BAR: NOT VISIBLE (may complete too fast to show)")

    # Cleanup
    print("\nCleaning up...")
    sender_client.close()
    receiver_client.close()
    kill_daemons()

    return 0


if __name__ == "__main__":
    sys.exit(main())
