import argparse
import subprocess
import sys
import shutil
import os
import threading # <--- NEW IMPORT
from pathlib import Path

# Import existing scripts as modules
from django_core_micha.scripts import generate_env, sync_secrets

def run_command(command, cwd=None, ignore_errors=False, shell=False, capture_output=False):
    """Helper function to execute shell commands."""
    # Only print command if not capturing output (avoids log spam in threads)
    if not capture_output:
        print(f"[INFO] Running: {' '.join(command) if isinstance(command, list) else command}")
    
    try:
        is_windows = sys.platform == "win32"
        use_shell = shell or is_windows
        
        # If capture_output is True, we return the process object instead of running to completion immediately
        if capture_output:
            return subprocess.Popen(command, cwd=cwd, shell=use_shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        
        subprocess.run(command, check=True, cwd=cwd, shell=use_shell)
    except subprocess.CalledProcessError as e:
        if ignore_errors:
            print(f"[WARN] Command failed (ignored): {e}")
        else:
            print(f"[ERROR] Command failed: {e}")
            sys.exit(e.returncode)

def stream_docker_logs(compose_files_args):
    """
    Runs in a separate thread to stream docker logs while frontend is running.
    """
    print("[INFO] Starting Docker Log Stream (Backend & Workers)...")
    # We filter for specific services to reduce noise, or remove service names to log everything
    # Services: backend, celery_worker, java_backend (if present)
    cmd = ["docker-compose"] + compose_files_args + ["logs", "-f", "--tail=100", "backend", "celery_worker", "java_backend"]
    
    try:
        # We run this directly. Since it's a thread, it won't block the main pnpm process.
        # However, subprocess.run handles the stream to stdout automatically.
        subprocess.run(cmd, check=False, shell=(sys.platform == "win32"))
    except Exception as e:
        print(f"[WARN] Log stream interrupted: {e}")

def main():
    parser = argparse.ArgumentParser(description="Developer Runner for Docker setup")
    parser.add_argument("--local", action="store_true", help="Sync local secrets and run in local mode")
    parser.add_argument("--edge", action="store_true", help="Run in edge mode (uses docker-compose.edge.yml)")
    parser.add_argument("--all", action="store_true", help="Sync ALL secrets (GitHub + Local)")
    
    args = parser.parse_args()

    # Set logic flags
    sync_local = args.local or args.all
    sync_github = args.all
    env_mode = "edge" if args.edge else "local"
    
    # Determine Compose files
    compose_files_args = ["-f", "docker-compose.yml"]
    
    if args.edge:
        edge_file = "docker-compose.edge.yml"
        if Path(edge_file).exists():
             compose_files_args.extend(["-f", edge_file])
        else:
             print(f"[WARN] {edge_file} für Edge-Mode nicht gefunden.")

    elif args.local:
        local_file = "docker-compose.local.yml"
        override_file = "docker-compose.override.yml"
        
        if Path(local_file).exists():
            print(f"[INFO] Nutze lokale Konfiguration: {local_file}")
            compose_files_args.extend(["-f", local_file])
        elif Path(override_file).exists():
            print(f"[INFO] {local_file} nicht gefunden. Falle zurück auf: {override_file}")
            compose_files_args.extend(["-f", override_file])
        else:
            print("[WARN] Weder .local.yml noch .override.yml gefunden. Starte nur Basis-Konfiguration.")
    
    print(f"[INFO] Genutzte Compose-Dateien: {' '.join(compose_files_args)}")

    # --- 1. Secrets Sync ---
    if sync_local:
        print("[INFO] Syncing local secrets (.env.local)...")
        sys.argv = ["sync-secrets", "--target", "local"]
        sync_secrets.main()

    if sync_github:
        print("[INFO] Syncing GitHub secrets...")
        sys.argv = ["sync-secrets", "--target", "github"]
        sync_secrets.main()

    # --- 2. Generate .env ---
    print(f"[INFO] Generating .env for environment: {env_mode}...")
    sys.argv = ["generate-env", "--env", env_mode]
    generate_env.main()

    # --- 3. Copy .env to frontend ---
    frontend_dir = Path("frontend")
    frontend_env_path = frontend_dir / ".env"
    
    if frontend_dir.exists():
        print("[INFO] Copying .env to frontend...")
        shutil.copy(".env", frontend_env_path)
    else:
        print("[WARN] 'frontend' folder not found. Skipping .env copy.")

    # --- 4. Cleanup ---
    print("[INFO] Cleaning up conflicting containers...")
    run_command(["docker", "rm", "-f", "traefik"], ignore_errors=True)
    
    cleanup_cmd = ["docker-compose"] + compose_files_args + ["rm", "-s", "-f", "-v", "backend", "celery_worker"]
    run_command(cleanup_cmd, ignore_errors=True)

    # --- 5. Build ---
    print("[INFO] Building containers...")
    build_cmd = ["docker-compose"] + compose_files_args + ["build"]
    run_command(build_cmd)

    # --- 6. Up ---
    print("[INFO] Starting containers...")
    # Detached mode is mandatory here so Python can continue
    up_cmd = ["docker-compose"] + compose_files_args + ["up", "-d", "--remove-orphans"]
    run_command(up_cmd)

    print(f"\n[SUCCESS] Backend is running.")

    # --- DEBUG START ---
    print(f"[DEBUG] frontend_dir: {frontend_dir.resolve()}")
    print(f"[DEBUG] frontend_dir.exists(): {frontend_dir.exists()}")
    print(f"[DEBUG] args.local: {args.local}")
    # --- DEBUG END ---

    # --- 7. Frontend & Logs Combined ---
    # Prüfen, ob wir im lokalen Modus sind und Frontend existiert
    if frontend_dir.exists() and args.local:
        print("\n[INFO] Starting Frontend Dev Server + Backend Logs in parallel...")
        print("[INFO] Press CTRL+C to stop both.")
        
        # Start Docker Logs in a background thread
        # (daemon=True heißt: Der Thread stirbt automatisch, wenn das Hauptskript beendet wird)
        log_thread = threading.Thread(target=stream_docker_logs, args=(compose_files_args,), daemon=True)
        log_thread.start()

        # Run Frontend in Main Thread (Blocking)
        try:
            # Windows/Shell Support:
            pnpm_cmd = "pnpm install && pnpm dev"
            subprocess.run(pnpm_cmd, cwd="frontend", shell=True, check=True)
        except KeyboardInterrupt:
            print("\n[INFO] Stopping...")
        except subprocess.CalledProcessError as e:
            print(f"[ERROR] Frontend process failed: {e}")
    else:
        # Fallback für Edge-Mode oder wenn kein Frontend da ist
        print(f"To follow logs run: docker-compose logs -f")

if __name__ == "__main__":
    main()