#!/usr/bin/env python3
"""
Unraid VM Manager for ThrillWiki - Main Orchestrator
Follows the Ubuntu autoinstall guide exactly:
1. Creates modified Ubuntu ISO with autoinstall configuration
2. Manages VM lifecycle on Unraid server
3. Handles ThrillWiki deployment automation
"""

import os
import sys
import logging
from pathlib import Path

# Import our modular components
from iso_builder import UbuntuISOBuilder
from vm_manager import UnraidVMManager

# Configuration
UNRAID_HOST = os.environ.get("UNRAID_HOST", "localhost")
UNRAID_USER = os.environ.get("UNRAID_USER", "root")
VM_NAME = os.environ.get("VM_NAME", "thrillwiki-vm")
VM_MEMORY = int(os.environ.get("VM_MEMORY", 4096))  # MB
VM_VCPUS = int(os.environ.get("VM_VCPUS", 2))
VM_DISK_SIZE = int(os.environ.get("VM_DISK_SIZE", 50))  # GB
SSH_PUBLIC_KEY = os.environ.get("SSH_PUBLIC_KEY", "")

# Network Configuration
VM_IP = os.environ.get("VM_IP", "dhcp")
VM_GATEWAY = os.environ.get("VM_GATEWAY", "192.168.20.1")
VM_NETMASK = os.environ.get("VM_NETMASK", "255.255.255.0")
VM_NETWORK = os.environ.get("VM_NETWORK", "192.168.20.0/24")

# GitHub Configuration
REPO_URL = os.environ.get("REPO_URL", "")
GITHUB_USERNAME = os.environ.get("GITHUB_USERNAME", "")
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")

# Ubuntu version preference
UBUNTU_VERSION = os.environ.get("UBUNTU_VERSION", "24.04")

# Setup logging
os.makedirs("logs", exist_ok=True)
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    handlers=[
        logging.FileHandler("logs/unraid-vm.log"),
        logging.StreamHandler(),
    ],
)
logger = logging.getLogger(__name__)


class ThrillWikiVMOrchestrator:
    """Main orchestrator for ThrillWiki VM deployment."""

    def __init__(self):
        self.vm_manager = UnraidVMManager(VM_NAME, UNRAID_HOST, UNRAID_USER)
        self.iso_builder = None

    def create_autoinstall_user_data(self) -> str:
        """Create autoinstall user-data configuration."""
        # Read autoinstall template
        template_path = Path(__file__).parent / "autoinstall-user-data.yaml"
        if not template_path.exists():
            raise FileNotFoundError(f"Autoinstall template not found: {template_path}")

        with open(template_path, "r", encoding="utf-8") as f:
            template = f.read()

        # Replace placeholders using string replacement (avoiding .format() due
        # to curly braces in YAML)
        user_data = template.replace(
            "{SSH_PUBLIC_KEY}",
            SSH_PUBLIC_KEY if SSH_PUBLIC_KEY else "# No SSH key provided",
        ).replace("{GITHUB_REPO}", REPO_URL if REPO_URL else "")

        # Update network configuration based on VM_IP setting
        if VM_IP.lower() == "dhcp":
            # Keep DHCP configuration as-is
            pass
        else:
            # Replace with static IP configuration
            network_config = f"""dhcp4: false
      addresses:
        - {VM_IP}/24
      gateway4: {VM_GATEWAY}
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4"""
            user_data = user_data.replace("dhcp4: true", network_config)

        return user_data

    def build_autoinstall_iso(self) -> Path:
        """Build Ubuntu autoinstall ISO following the guide."""
        logger.info("🔨 Building Ubuntu autoinstall ISO...")

        # Create ISO builder
        self.iso_builder = UbuntuISOBuilder(VM_NAME)

        # Create user-data configuration
        user_data = self.create_autoinstall_user_data()

        # Build autoinstall ISO
        iso_output_path = Path(f"/tmp/{VM_NAME}-ubuntu-autoinstall.iso")

        success = self.iso_builder.build_autoinstall_iso(
            user_data=user_data,
            output_path=iso_output_path,
            ubuntu_version=UBUNTU_VERSION,
        )

        if not success:
            raise RuntimeError("Failed to build autoinstall ISO")

        logger.info(f"✅ Autoinstall ISO built successfully: {iso_output_path}")
        return iso_output_path

    def deploy_vm(self) -> bool:
        """Complete VM deployment process."""
        try:
            logger.info("🚀 Starting ThrillWiki VM deployment...")

            # Step 1: Check SSH connectivity
            logger.info("📡 Testing Unraid connectivity...")
            if not self.vm_manager.authenticate():
                logger.error("❌ Cannot connect to Unraid server")
                return False

            # Step 2: Build autoinstall ISO
            logger.info("🔨 Building Ubuntu autoinstall ISO...")
            iso_path = self.build_autoinstall_iso()

            # Step 3: Upload ISO to Unraid
            logger.info("📤 Uploading autoinstall ISO to Unraid...")
            self.vm_manager.upload_iso_to_unraid(iso_path)

            # Step 4: Create/update VM configuration
            logger.info("⚙️  Creating VM configuration...")
            success = self.vm_manager.create_vm(
                vm_memory=VM_MEMORY,
                vm_vcpus=VM_VCPUS,
                vm_disk_size=VM_DISK_SIZE,
                vm_ip=VM_IP,
            )

            if not success:
                logger.error("❌ Failed to create VM configuration")
                return False

            # Step 5: Start VM
            logger.info("🟢 Starting VM...")
            success = self.vm_manager.start_vm()

            if not success:
                logger.error("❌ Failed to start VM")
                return False

            logger.info("🎉 VM deployment completed successfully!")
            logger.info("")
            logger.info("📋 Next Steps:")
            logger.info("1. VM is now booting with Ubuntu autoinstall")
            logger.info("2. Installation will take 15-30 minutes")
            logger.info("3. Use 'python main.py ip' to get VM IP when ready")
            logger.info("4. SSH to VM and run /home/thrillwiki/deploy-thrillwiki.sh")
            logger.info("")

            return True

        except Exception as e:
            logger.error(f"❌ VM deployment failed: {e}")
            return False
        finally:
            # Cleanup ISO builder temp files
            if self.iso_builder:
                self.iso_builder.cleanup()

    def get_vm_info(self) -> dict:
        """Get VM information."""
        return {
            "name": VM_NAME,
            "status": self.vm_manager.vm_status(),
            "ip": self.vm_manager.get_vm_ip(),
            "memory": VM_MEMORY,
            "vcpus": VM_VCPUS,
            "disk_size": VM_DISK_SIZE,
        }


def main():
    """Main entry point."""
    import argparse

    parser = argparse.ArgumentParser(
        description="ThrillWiki VM Manager - Ubuntu Autoinstall on Unraid",
        epilog="""
Examples:
  python main.py setup     # Complete VM setup with autoinstall
  python main.py start     # Start existing VM
  python main.py ip        # Get VM IP address
  python main.py status    # Get VM status
  python main.py delete    # Remove VM completely
        """,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    parser.add_argument(
        "action",
        choices=[
            "setup",
            "create",
            "start",
            "stop",
            "status",
            "ip",
            "delete",
            "info",
        ],
        help="Action to perform",
    )

    args = parser.parse_args()

    # Create orchestrator
    orchestrator = ThrillWikiVMOrchestrator()

    if args.action == "setup":
        logger.info("🚀 Setting up complete ThrillWiki VM environment...")
        success = orchestrator.deploy_vm()
        sys.exit(0 if success else 1)

    elif args.action == "create":
        logger.info("⚙️  Creating VM configuration...")
        success = orchestrator.vm_manager.create_vm(
            VM_MEMORY, VM_VCPUS, VM_DISK_SIZE, VM_IP
        )
        sys.exit(0 if success else 1)

    elif args.action == "start":
        logger.info("🟢 Starting VM...")
        success = orchestrator.vm_manager.start_vm()
        sys.exit(0 if success else 1)

    elif args.action == "stop":
        logger.info("🛑 Stopping VM...")
        success = orchestrator.vm_manager.stop_vm()
        sys.exit(0 if success else 1)

    elif args.action == "status":
        status = orchestrator.vm_manager.vm_status()
        print(f"VM Status: {status}")
        sys.exit(0)

    elif args.action == "ip":
        ip = orchestrator.vm_manager.get_vm_ip()
        if ip:
            print(f"VM IP: {ip}")
            print(f"SSH: ssh thrillwiki@{ip}")
            print(
                f"Deploy: ssh thrillwiki@{ip} '/home/thrillwiki/deploy-thrillwiki.sh'"
            )
            sys.exit(0)
        else:
            print("❌ Failed to get VM IP (VM may not be ready yet)")
            sys.exit(1)

    elif args.action == "info":
        info = orchestrator.get_vm_info()
        print("🖥️  VM Information:")
        print(f"   Name: {info['name']}")
        print(f"   Status: {info['status']}")
        print(f"   IP: {info['ip'] or 'Not available'}")
        print(f"   Memory: {info['memory']} MB")
        print(f"   vCPUs: {info['vcpus']}")
        print(f"   Disk: {info['disk_size']} GB")
        sys.exit(0)

    elif args.action == "delete":
        logger.info("🗑️  Deleting VM and all files...")
        success = orchestrator.vm_manager.delete_vm()
        sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()
