"""
DSON File Utilities

This module provides utility functions for managing DSON files,
including copying DSON files to UE Demo project for testing.
"""

import os
import shutil
import logging
from typing import Optional, List, Tuple
from pathlib import Path

# Try to import config module
try:
    import sys
    # Add project root to path if not already there
    _craftpilot_dir = Path(__file__).parent.parent
    _project_root = _craftpilot_dir.parent
    if str(_project_root) not in sys.path:
        sys.path.insert(0, str(_project_root))
    # Add Server dir to path for config module
    _server_dir = _project_root / 'Server'
    if str(_server_dir) not in sys.path:
        sys.path.insert(0, str(_server_dir))
    from config import (
        get_ue_demo_dson_path,
        get_ue_demo_project_path,
        is_ue_demo_project_configured,
        ensure_dson_directory
    )
    _CONFIG_AVAILABLE = True
except ImportError:
    _CONFIG_AVAILABLE = False

logger = logging.getLogger(__name__)


def get_dson_source_directory() -> str:
    """
    Get the source directory for DSON files.
    
    Returns:
        Path to the pypapi/dson directory.
    """
    return os.path.join(os.path.dirname(__file__), "dson")


def list_available_dson_files() -> List[str]:
    """
    List all available DSON files in the source directory.
    
    Returns:
        List of DSON file names (without path).
    """
    dson_dir = get_dson_source_directory()
    if not os.path.exists(dson_dir):
        return []
    
    return [f for f in os.listdir(dson_dir) if f.endswith('.dson')]


def copy_dson_to_ue_demo(
    dson_filename: str,
    target_filename: Optional[str] = None,
    overwrite: bool = True
) -> Tuple[bool, str]:
    """
    Copy a DSON file to the UE Demo project's DSON directory.
    
    Args:
        dson_filename: Name of the DSON file to copy (e.g., "test_add_int.dson").
                      Can be just the filename or a full path.
        target_filename: Optional target filename. If None, uses the source filename.
        overwrite: If True, overwrite existing file. If False, skip if exists.
        
    Returns:
        Tuple of (success: bool, message: str)
    """
    if not _CONFIG_AVAILABLE:
        return False, "Configuration module not available"
    
    if not is_ue_demo_project_configured():
        return False, "UE Demo project is not configured"
    
    # Determine source path
    if os.path.isabs(dson_filename):
        source_path = dson_filename
    else:
        # Look in pypapi/dson directory
        source_path = os.path.join(get_dson_source_directory(), dson_filename)
    
    if not os.path.exists(source_path):
        return False, f"Source file not found: {source_path}"
    
    # Ensure target directory exists
    target_dir = ensure_dson_directory()
    if target_dir is None:
        return False, "Failed to create DSON directory in UE Demo project"
    
    # Determine target filename
    if target_filename is None:
        target_filename = os.path.basename(source_path)
    
    target_path = os.path.join(target_dir, target_filename)
    
    # Check if file exists
    if os.path.exists(target_path) and not overwrite:
        return True, f"File already exists (skipped): {target_path}"
    
    try:
        shutil.copy2(source_path, target_path)
        logger.info(f"Copied DSON file: {source_path} -> {target_path}")
        return True, f"Successfully copied to: {target_path}"
    except Exception as e:
        return False, f"Failed to copy file: {str(e)}"


def copy_all_dson_files(
    pattern: Optional[str] = None,
    overwrite: bool = True
) -> List[Tuple[str, bool, str]]:
    """
    Copy all DSON files (or those matching a pattern) to the UE Demo project.
    
    Args:
        pattern: Optional pattern to filter files (e.g., "test_" to copy all test files).
        overwrite: If True, overwrite existing files.
        
    Returns:
        List of (filename, success, message) tuples.
    """
    results = []
    
    dson_files = list_available_dson_files()
    
    if pattern:
        dson_files = [f for f in dson_files if pattern in f]
    
    for filename in dson_files:
        success, message = copy_dson_to_ue_demo(filename, overwrite=overwrite)
        results.append((filename, success, message))
    
    return results


def copy_dson_from_path(
    source_path: str,
    target_filename: Optional[str] = None,
    overwrite: bool = True
) -> Tuple[bool, str]:
    """
    Copy a DSON file from any path to the UE Demo project.
    
    Args:
        source_path: Full path to the source DSON file.
        target_filename: Optional target filename. If None, uses the source filename.
        overwrite: If True, overwrite existing file.
        
    Returns:
        Tuple of (success: bool, message: str)
    """
    return copy_dson_to_ue_demo(source_path, target_filename, overwrite)


def get_ue_dson_path(dson_filename: str) -> Optional[str]:
    """
    Get the full path to a DSON file in the UE Demo project.
    
    Args:
        dson_filename: Name of the DSON file.
        
    Returns:
        Full path to the DSON file in UE Demo project, or None if not configured.
    """
    if not _CONFIG_AVAILABLE or not is_ue_demo_project_configured():
        return None
    
    dson_dir = get_ue_demo_dson_path()
    if dson_dir is None:
        return None
    
    return os.path.join(dson_dir, dson_filename)


def sync_dson_files(overwrite: bool = False) -> dict:
    """
    Synchronize all DSON files to the UE Demo project.
    Only copies files that don't exist or have been modified.
    
    Args:
        overwrite: If True, overwrite all files regardless of modification time.
        
    Returns:
        Dictionary with sync results:
        {
            "copied": [...],
            "skipped": [...],
            "failed": [...]
        }
    """
    results = {
        "copied": [],
        "skipped": [],
        "failed": []
    }
    
    if not _CONFIG_AVAILABLE or not is_ue_demo_project_configured():
        results["failed"].append(("*", "UE Demo project not configured"))
        return results
    
    dson_files = list_available_dson_files()
    target_dir = ensure_dson_directory()
    
    if target_dir is None:
        results["failed"].append(("*", "Failed to create target directory"))
        return results
    
    for filename in dson_files:
        source_path = os.path.join(get_dson_source_directory(), filename)
        target_path = os.path.join(target_dir, filename)
        
        # Check if we need to copy
        should_copy = overwrite or not os.path.exists(target_path)
        
        if not should_copy:
            # Check modification time
            source_mtime = os.path.getmtime(source_path)
            target_mtime = os.path.getmtime(target_path)
            should_copy = source_mtime > target_mtime
        
        if should_copy:
            success, message = copy_dson_to_ue_demo(filename, overwrite=True)
            if success:
                results["copied"].append(filename)
            else:
                results["failed"].append((filename, message))
        else:
            results["skipped"].append(filename)
    
    return results


if __name__ == "__main__":
    # Test the module
    print("DSON Utilities Test")
    print("=" * 50)
    
    print(f"\nSource directory: {get_dson_source_directory()}")
    
    dson_files = list_available_dson_files()
    print(f"\nAvailable DSON files ({len(dson_files)}):")
    for f in dson_files[:10]:
        print(f"  - {f}")
    if len(dson_files) > 10:
        print(f"  ... and {len(dson_files) - 10} more")
    
    if _CONFIG_AVAILABLE and is_ue_demo_project_configured():
        print(f"\nUE Demo project configured: Yes")
        print(f"UE Demo DSON path: {get_ue_demo_dson_path()}")
        
        # Test copying a single file
        print("\nTesting copy of test_add_int.dson:")
        success, message = copy_dson_to_ue_demo("test_add_int.dson")
        print(f"  Result: {message}")
    else:
        print("\nUE Demo project: Not configured")
