"""
RAGSentinel CLI - Command Line Interface
"""

import os
import sys
import shutil
import socket
import subprocess
import time
import argparse
from pathlib import Path

# Get the templates directory path
TEMPLATES_DIR = Path(__file__).parent / "templates"


def is_port_in_use(host, port):
    """Check if a port is in use."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex((host, port)) == 0


def start_mlflow_server(host="127.0.0.1", port=5001):
    """Start MLflow server as a background process."""
    if is_port_in_use(host, port):
        print(f"✓ MLflow server already running at http://{host}:{port}")
        return None
    
    print(f"🚀 Starting MLflow server at http://{host}:{port}...")
    
    process = subprocess.Popen(
        [sys.executable, "-m", "mlflow", "server", "--host", host, "--port", str(port)],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
    )
    
    # Wait for server to start
    for _ in range(10):
        time.sleep(1)
        if is_port_in_use(host, port):
            print(f"✓ MLflow server started at http://{host}:{port}")
            return process
    
    print("⚠ MLflow server may not have started properly")
    return process


def cmd_init(args):
    """Initialize project with config templates."""
    print("=" * 50)
    print("RAGSentinel - Project Initialization")
    print("=" * 50)
    
    files_to_copy = [
        (".env.template", ".env"),
        ("config.ini.template", "config.ini"),
        ("rag_eval_config.yaml", "rag_eval_config.yaml"),
    ]
    
    for src_name, dest_name in files_to_copy:
        src_path = TEMPLATES_DIR / src_name
        dest_path = Path.cwd() / dest_name
        
        if dest_path.exists() and not args.force:
            print(f"⚠ {dest_name} already exists (use --force to overwrite)")
        else:
            if src_path.exists():
                shutil.copy(src_path, dest_path)
                print(f"✓ Created {dest_name}")
            else:
                print(f"✗ Template not found: {src_name}")
    
    print("\n" + "=" * 50)
    print("Next steps:")
    print("  1. Edit .env with your LLM/Embeddings API keys")
    print("  2. Edit config.ini with your app settings")
    print("  3. Create test_dataset.csv with your test data")
    print("  4. Run: rag-sentinel run")
    print("=" * 50)


def cmd_run(args):
    """Run the RAG evaluation."""
    # Check if config files exist
    required_files = [".env", "config.ini", "rag_eval_config.yaml"]
    missing_files = [f for f in required_files if not Path(f).exists()]
    
    if missing_files:
        print("❌ Missing configuration files:")
        for f in missing_files:
            print(f"   - {f}")
        print("\nRun 'rag-sentinel init' first to create config files.")
        sys.exit(1)
    
    # Start MLflow server if not running
    if not args.no_server:
        start_mlflow_server()
    
    # Import and run evaluation
    from rag_sentinel.evaluator import run_evaluation
    run_evaluation()


def cmd_validate(args):
    """Validate configuration files."""
    print("=" * 50)
    print("RAGSentinel - Configuration Validation")
    print("=" * 50)
    
    # Check files exist
    files_to_check = [".env", "config.ini", "rag_eval_config.yaml"]
    all_exist = True
    
    for f in files_to_check:
        if Path(f).exists():
            print(f"✓ {f} exists")
        else:
            print(f"✗ {f} missing")
            all_exist = False
    
    if not all_exist:
        print("\n❌ Some files are missing. Run 'rag-sentinel init' first.")
        return
    
    # Try to load config
    try:
        from rag_sentinel.evaluator import load_config
        config = load_config()
        print("\n✓ Configuration loaded successfully")
        print(f"  - LLM Provider: {config['ragas']['llm']['provider']}")
        print(f"  - Embeddings Provider: {config['ragas']['embeddings']['provider']}")
        print(f"  - Backend URL: {config['backend']['base_url']}")
        print(f"  - Dataset: {config['dataset']['path']}")
    except Exception as e:
        print(f"\n❌ Configuration error: {e}")


def main():
    """Main entry point for CLI."""
    parser = argparse.ArgumentParser(
        prog="rag-sentinel",
        description="RAGSentinel - RAG Evaluation Framework using Ragas and MLflow"
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Available commands")
    
    # init command
    init_parser = subparsers.add_parser("init", help="Initialize project with config templates")
    init_parser.add_argument("--force", "-f", action="store_true", help="Overwrite existing files")
    
    # run command
    run_parser = subparsers.add_parser("run", help="Run RAG evaluation")
    run_parser.add_argument("--no-server", action="store_true", help="Don't start MLflow server")
    
    # validate command
    validate_parser = subparsers.add_parser("validate", help="Validate configuration files")
    
    args = parser.parse_args()
    
    if args.command == "init":
        cmd_init(args)
    elif args.command == "run":
        cmd_run(args)
    elif args.command == "validate":
        cmd_validate(args)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()

