#!/usr/bin/env python3
"""
DWG to DXF Batch Converter using ODA File Converter

This script finds all .dwg files in the current directory and subdirectories,
then converts them to .dxf format using the ODA File Converter.

Requirements:
    - ODA File Converter must be installed
    - Download from: https://www.opendesign.com/guestfiles/oda_file_converter

Usage:
    python convert_dwg_to_dxf.py

Output:
    Creates .dxf files in parallel directory structure with '-dxf' suffix
    Example: '2-POA/file.dwg' → '2-POA-dxf/file.dxf'
    Files in root directory → 'root-dxf/file.dxf'

Written by Douglas Millner of NERX Power Consultants LLC - Social, Website, and Blog - https://linktr.ee/nerxpower

DISCLAIMER: The software is free for distribution. The user assumes all risk.
"""

import os
import sys
import subprocess
import shutil
from pathlib import Path

# Always run from the script's directory
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(SCRIPT_DIR)

def find_oda_converter():
    """
    Try to find the ODA File Converter executable.
    Common installation paths on Windows.
    """
    # Check if ODAFileConverter is in PATH
    if shutil.which("ODAFileConverter"):
        return "ODAFileConverter"
    
    # Check for versioned installations in Program Files
    base_paths = [
        r"C:\Program Files\ODA",
        r"C:\Program Files (x86)\ODA",
        r"C:\ODA",
    ]
    
    for base_path in base_paths:
        if os.path.exists(base_path):
            # Look for ODAFileConverter folders (may be versioned)
            for item in os.listdir(base_path):
                item_path = os.path.join(base_path, item)
                if os.path.isdir(item_path) and 'ODAFileConverter' in item:
                    exe_path = os.path.join(item_path, 'ODAFileConverter.exe')
                    if os.path.exists(exe_path):
                        return exe_path
    
    return None

def show_welcome_screen():
    """Display welcome screen with instructions and wait for user to continue."""
    # Clear screen (works on Windows and Unix)
    os.system('cls' if os.name == 'nt' else 'clear')
    
    print("=" * 80)
    print(" " * 25 + "DWG TO DXF BATCH CONVERTER")
    print("=" * 80)
    print()
    print("📋 WHAT THIS SCRIPT DOES:")
    print("-" * 80)
    print("  • Scans ALL .dwg files in THIS directory and ALL subdirectories")
    print("  • Recursively searches through every folder and subfolder")
    print("  • Converts each .dwg file to .dxf format using ODA File Converter")
    print("  • Creates .dxf files in parallel directory structure with '-dxf' suffix")
    print("  • Files in root directory are placed in 'root-dxf' folder")
    print("  • Skips files if .dxf already exists (to save time)")
    print()
    print("📁 SEARCH LOCATION:")
    print("-" * 80)
    print(f"  Starting from: {os.getcwd()}")
    print(f"  Searching: THIS DIRECTORY + ALL SUBDIRECTORIES (recursive)")
    print()
    print("🔧 REQUIREMENTS:")
    print("-" * 80)
    print("  • ODA File Converter must be installed")
    print("  • Download from: https://www.opendesign.com/guestfiles/oda_file_converter")
    print("  • Free to download and use")
    print()
    print("📊 CONVERSION SETTINGS:")
    print("-" * 80)
    print("  • Output format: DXF")
    print("  • Output version: AutoCAD 2018 DXF")
    print("  • Preserves original file structure")
    print()
    print("⏱️  ESTIMATED TIME:")
    print("-" * 80)
    print("  • Depends on number and size of .dwg files")
    print("  • Progress will be shown for each file")
    print()
    print("⚠️  NOTE:")
    print("-" * 80)
    print("  • Original .dwg files will NOT be modified or deleted")
    print("  • .dxf files will be created in directories with '-dxf' suffix")
    print("  • Example: '2-POA/file.dwg' → '2-POA-dxf/file.dxf'")
    print("  • Files in root directory → 'root-dxf/file.dxf'")
    print("  • If .dxf already exists, conversion is skipped")
    print()
    print("=" * 80)
    print("Written by Douglas Millner of NERX Power Consultants LLC")
    print("Social, Website, and Blog - https://linktr.ee/nerxpower")
    print("DISCLAIMER: The software is free for distribution. The user assumes all risk.")
    print("=" * 80)
    print()
    print("⌨️  Press ENTER to continue or Ctrl+C to cancel...")
    print()
    
    try:
        input()
    except KeyboardInterrupt:
        print("\n\n❌ Operation cancelled by user.")
        exit(0)
    
    # Clear screen again before showing progress
    os.system('cls' if os.name == 'nt' else 'clear')

def find_dwg_files(root_dir):
    """Find all .dwg files recursively."""
    dwg_files = []
    
    for root, dirs, files in os.walk(root_dir):
        for filename in files:
            if filename.lower().endswith('.dwg'):
                filepath = os.path.join(root, filename)
                dwg_files.append(filepath)
    
    return dwg_files

def get_dxf_output_path(dwg_path, root_dir):
    """
    Convert a DWG file path to its corresponding DXF output path.
    Adds '-dxf' suffix to each directory in the path.
    Files in root directory are placed in 'root-dxf' folder.
    
    Example:
        Input:  c:/project/2-POA/subfolder/file.dwg
        Output: c:/project/2-POA-dxf/subfolder-dxf/file.dxf
        Input:  c:/project/file.dwg
        Output: c:/project/root-dxf/file.dxf
    """
    # Get the relative path from root
    rel_path = os.path.relpath(dwg_path, root_dir)
    
    # Split into directory and filename
    dir_part = os.path.dirname(rel_path)
    filename = os.path.basename(rel_path)
    
    # Replace .dwg with .dxf
    dxf_filename = filename[:-4] + '.dxf' if filename.lower().endswith('.dwg') else filename + '.dxf'
    
    # If the file is in root (no subdirectory), put it in 'root-dxf' directory
    if not dir_part or dir_part == '.':
        return os.path.join(root_dir, 'root-dxf', dxf_filename)
    
    # Split the directory path into components and add -dxf suffix to each
    path_parts = []
    while dir_part and dir_part != '.':
        head, tail = os.path.split(dir_part)
        if tail:
            path_parts.insert(0, tail + '-dxf')
        dir_part = head
    
    # Reconstruct the path with -dxf suffixes
    new_dir = os.path.join(root_dir, *path_parts) if path_parts else root_dir
    
    return os.path.join(new_dir, dxf_filename)

def convert_file_with_oda(oda_path, input_file, output_dir):
    """
    Convert a single DWG file to DXF using ODA File Converter.
    
    ODA File Converter command syntax:
    ODAFileConverter "input_folder" "output_folder" "ACAD_version" "output_format" "recurse" "audit"
    """
    try:
        # Create a temporary folder structure for ODA converter
        input_dir = os.path.dirname(input_file)
        
        # ODA File Converter parameters
        # ACAD2018 = AutoCAD 2018 DXF format
        # DXF = output format
        # 0 = don't recurse (we handle that ourselves)
        # 1 = audit files
        
        cmd = [
            oda_path,
            input_dir,      # Input folder
            output_dir,     # Output folder
            "ACAD2018",     # Output version
            "DXF",          # Output format
            "0",            # Don't recurse
            "1"             # Audit
        ]
        
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=300  # 5 minute timeout per file
        )
        
        return result.returncode == 0
        
    except subprocess.TimeoutExpired:
        print("      ⚠️ Timeout - file may be too large or corrupted")
        return False
    except Exception as e:
        print(f"      ⚠️ Error: {e}")
        return False

def batch_convert(root_dir):
    """Convert all DWG files to DXF."""
    print("=" * 80)
    print("STARTING DWG TO DXF CONVERSION")
    print("=" * 80)
    print()
    
    # Find ODA File Converter
    print("🔍 Locating ODA File Converter...")
    oda_path = find_oda_converter()
    
    if not oda_path:
        print()
        print("=" * 80)
        print("❌ ERROR: ODA File Converter not found!")
        print("=" * 80)
        print()
        print("Please install ODA File Converter:")
        print("  1. Download from: https://www.opendesign.com/guestfiles/oda_file_converter")
        print("  2. Install to default location")
        print("  3. Run this script again")
        print()
        print("Press ENTER to exit...")
        input()
        return
    
    print(f"  ✓ Found: {oda_path}")
    print()
    
    # Find all DWG files
    print("📂 Scanning for .dwg files...")
    dwg_files = find_dwg_files(root_dir)
    
    if not dwg_files:
        print()
        print("=" * 80)
        print("⚠️  NO DWG FILES FOUND")
        print("=" * 80)
        print()
        print(f"No .dwg files were found in: {root_dir}")
        print("Make sure you placed this script in the correct directory.")
        print()
        print("Press ENTER to exit...")
        input()
        return
    
    print(f"  ✓ Found {len(dwg_files)} .dwg files")
    print()
    
    # Check which files need conversion
    files_to_convert = []
    files_skipped = 0
    
    for dwg_file in dwg_files:
        dxf_file = get_dxf_output_path(dwg_file, root_dir)
        if os.path.exists(dxf_file):
            files_skipped += 1
        else:
            files_to_convert.append(dwg_file)
    
    print("=" * 80)
    print("CONVERSION SUMMARY")
    print("=" * 80)
    print(f"  Total .dwg files found: {len(dwg_files)}")
    print(f"  Already converted (skipped): {files_skipped}")
    print(f"  Files to convert: {len(files_to_convert)}")
    print()
    
    if len(files_to_convert) == 0:
        print("✅ All files are already converted!")
        print()
        print("Press ENTER to exit...")
        input()
        return
    
    print("⏱️  Starting conversion...")
    print()
    
    # Convert files
    success_count = 0
    fail_count = 0
    
    for i, dwg_file in enumerate(files_to_convert, 1):
        relative_path = os.path.relpath(dwg_file, root_dir)
        print(f"  [{i}/{len(files_to_convert)}] {relative_path}")
        
        # Get the output directory with -dxf suffix
        dxf_path = get_dxf_output_path(dwg_file, root_dir)
        output_dir = os.path.dirname(dxf_path)
        
        # Create output directory if it doesn't exist
        os.makedirs(output_dir, exist_ok=True)
        
        # Convert
        if convert_file_with_oda(oda_path, dwg_file, output_dir):
            success_count += 1
            print(f"      ✓ Converted successfully")
        else:
            fail_count += 1
            print(f"      ✗ Conversion failed")
        
        print()
    
    # Final summary
    print("=" * 80)
    print("✅ CONVERSION COMPLETE!")
    print("=" * 80)
    print(f"  Successful: {success_count}")
    print(f"  Failed: {fail_count}")
    print(f"  Skipped (already existed): {files_skipped}")
    print(f"  Total: {len(dwg_files)}")
    print()
    print("📝 NEXT STEPS:")
    print("  • All .dxf files have been created in directories with '-dxf' suffix")
    print("  • Files from root directory are in 'root-dxf' folder")
    print("  • You can now run build_drawing_index.py to index the drawings")
    print("  • Then use search_drawings_local.html to search them")
    print()
    print("⌨️  Press ENTER to exit...")
    
    try:
        input()
    except:
        pass

if __name__ == '__main__':
    # Show welcome screen
    show_welcome_screen()
    
    # Get the current directory (already changed to script directory)
    current_dir = os.getcwd()
    
    print("=" * 80)
    print("DWG TO DXF BATCH CONVERTER - RUNNING")
    print("=" * 80)
    print(f"📂 Working directory: {current_dir}")
    print()
    
    # Run the conversion
    batch_convert(current_dir)