/// Custom Transpiler Plugin Example
///
/// Demonstrates how to create a custom transpiler plugin for Batuta.
///
/// This example shows:
/// - Implementing the TranspilerPlugin trait
/// - Registering with PluginRegistry
/// - Integrating with the transpilation pipeline
/// - Custom language support
///
/// Run with: cargo run --example custom_plugin
use anyhow::Result;
use batuta::plugin::{PluginMetadata, PluginRegistry, TranspilerPlugin};
use batuta::types::Language;

/// Example: Simple Python→Rust transpiler for print statements
///
/// This is a minimal example that only handles print() statements.
/// Real plugins would implement full language transpilation.
struct SimplePythonTranspiler {
    print_count: usize,
}

impl SimplePythonTranspiler {
    fn new() -> Self {
        Self { print_count: 0 }
    }

    /// Convert Python print() to Rust println!()
    fn transpile_print(&self, content: &str) -> String {
        content.replace("print(", "println!(")
    }
}

impl TranspilerPlugin for SimplePythonTranspiler {
    fn metadata(&self) -> PluginMetadata {
        PluginMetadata {
            name: "simple-python-transpiler".to_string(),
            version: "0.1.0".to_string(),
            description: "Simple Python to Rust transpiler for print statements".to_string(),
            author: "Batuta Example".to_string(),
            supported_languages: vec![Language::Python],
        }
    }

    fn initialize(&mut self) -> Result<()> {
        println!("🔧 Initializing SimplePythonTranspiler");
        self.print_count = 0;
        Ok(())
    }

    fn transpile(&self, source: &str, language: Language) -> Result<String> {
        if language != Language::Python {
            return Err(anyhow::anyhow!(
                "SimplePythonTranspiler only supports Python"
            ));
        }

        let mut output = String::new();

        // Add Rust boilerplate
        output.push_str("// Auto-generated by SimplePythonTranspiler\n\n");
        output.push_str("fn main() {\n");

        // Transpile each line
        for line in source.lines() {
            let trimmed = line.trim();

            if trimmed.starts_with("print(") {
                // Convert print() to println!()
                let rust_line = self.transpile_print(trimmed);
                output.push_str("    ");
                output.push_str(&rust_line);
                output.push('\n');
            } else if !trimmed.is_empty() && !trimmed.starts_with('#') {
                // Comment out unsupported lines
                output.push_str("    // ");
                output.push_str(trimmed);
                output.push_str(" // [Not transpiled]\n");
            }
        }

        output.push_str("}\n");

        Ok(output)
    }

    fn validate(&self, original: &str, transpiled: &str) -> Result<()> {
        // Simple validation: check that we have main() function
        if !transpiled.contains("fn main()") {
            return Err(anyhow::anyhow!("Transpiled output missing main() function"));
        }

        // Check that print count matches
        let print_count = original.matches("print(").count();
        let println_count = transpiled.matches("println!(").count();

        if print_count != println_count {
            return Err(anyhow::anyhow!(
                "Print statement count mismatch: {} in original, {} in transpiled",
                print_count,
                println_count
            ));
        }

        Ok(())
    }

    fn cleanup(&mut self) -> Result<()> {
        println!("🧹 Cleaning up SimplePythonTranspiler");
        println!("   Transpiled {} print statements", self.print_count);
        Ok(())
    }
}

/// Example: Ruby→Rust transpiler (stub implementation)
struct RubyTranspiler;

impl TranspilerPlugin for RubyTranspiler {
    fn metadata(&self) -> PluginMetadata {
        PluginMetadata {
            name: "ruby-transpiler".to_string(),
            version: "0.1.0".to_string(),
            description: "Ruby to Rust transpiler (example)".to_string(),
            author: "Batuta Example".to_string(),
            supported_languages: vec![Language::Python], // Using Python enum as placeholder
        }
    }

    fn transpile(&self, source: &str, _language: Language) -> Result<String> {
        // Stub implementation
        Ok(format!(
            "// Ruby transpilation not yet implemented\n// Original:\n// {}\n",
            source
        ))
    }
}

fn main() -> Result<()> {
    println!("Custom Transpiler Plugin Example");
    println!("=================================\n");

    // Create plugin registry
    let mut registry = PluginRegistry::new();
    println!("📦 Created plugin registry\n");

    // Register SimplePythonTranspiler
    println!("1. Registering SimplePythonTranspiler...");
    let python_plugin = Box::new(SimplePythonTranspiler::new());
    registry.register(python_plugin)?;
    println!("   ✅ Registered\n");

    // Register RubyTranspiler
    println!("2. Registering RubyTranspiler...");
    let ruby_plugin = Box::new(RubyTranspiler);
    registry.register(ruby_plugin)?;
    println!("   ✅ Registered\n");

    // List all plugins
    println!("3. Listing registered plugins:");
    for name in registry.list_plugins() {
        println!("   • {}", name);
    }
    println!();

    // Show supported languages
    println!("4. Supported languages:");
    for lang in registry.supported_languages() {
        let plugins = registry.get_for_language(&lang);
        println!("   • {:?}: {} plugin(s)", lang, plugins.len());
    }
    println!();

    // Test transpilation
    println!("5. Testing SimplePythonTranspiler:\n");

    let python_code = r#"# Simple Python program
print("Hello, World!")
x = 42
print(f"The answer is {x}")
"#;

    println!("Input (Python):");
    println!("{}", python_code);

    if let Some(plugin) = registry.get("simple-python-transpiler") {
        match plugin.transpile(python_code, Language::Python) {
            Ok(rust_code) => {
                println!("Output (Rust):");
                println!("{}", rust_code);

                // Validate
                match plugin.validate(python_code, &rust_code) {
                    Ok(()) => println!("✅ Validation passed\n"),
                    Err(e) => println!("❌ Validation failed: {}\n", e),
                }
            }
            Err(e) => {
                println!("❌ Transpilation failed: {}\n", e);
            }
        }
    }

    // Get plugin by language
    println!("6. Looking up plugins by language:");
    let python_plugins = registry.get_for_language(&Language::Python);
    println!("   Found {} plugin(s) for Python:", python_plugins.len());
    for plugin in python_plugins {
        let meta = plugin.metadata();
        println!(
            "      • {} v{}: {}",
            meta.name, meta.version, meta.description
        );
    }
    println!();

    // Cleanup
    println!("7. Cleaning up plugins...");
    registry.cleanup_all()?;
    println!("   ✅ All plugins cleaned up\n");

    println!("🎉 Plugin example complete!");

    println!("\n💡 Next Steps:");
    println!("   • Implement full language support in your plugin");
    println!("   • Add advanced transpilation features (type inference, imports, etc.)");
    println!("   • Integrate plugin with Batuta pipeline using PluginStage");
    println!("   • Publish as a crate for others to use");
    println!("   • See docs/PLUGIN_GUIDE.md for detailed instructions");

    Ok(())
}
