// Trait System Basic Test Suite
// Testing trait definitions, implementations, and method resolution

#![allow(dead_code)]

use ruchy::runtime::repl::Repl;
use std::process::Command;
use std::fs;

// Helper to test in REPL
fn eval_in_repl(code: &str) -> Result<String, String> {
    let mut repl = Repl::new()
        .map_err(|e| format!("Failed to create REPL: {e:?}"))?;
    
    let result = repl.eval(code)
        .map_err(|e| format!("Eval error: {e:?}"))?;
    
    // Remove quotes if present (REPL string formatting)
    if result.starts_with('"') && result.ends_with('"') && result.len() >= 2 {
        Ok(result[1..result.len()-1].to_string())
    } else {
        Ok(result)
    }
}

// Helper to test transpiled code with unique filenames
fn eval_transpiled(code: &str) -> Result<String, String> {
    let test_file = format!("/tmp/traits_test_{}.ruchy", 
        std::process::id());
    fs::write(&test_file, code)
        .map_err(|e| format!("Failed to write test file: {e}"))?;
    
    let output = Command::new("./target/release/ruchy")
        .arg(&test_file)
        .output()
        .map_err(|e| format!("Failed to run file: {e}"))?;
    
    // Clean up
    let _ = fs::remove_file(&test_file);
    
    if !output.status.success() {
        return Err(format!("Execution failed: {}", 
            String::from_utf8_lossy(&output.stderr)));
    }
    
    Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}

#[test]
fn test_trait_definition() {
    // Test basic trait definition
    let code = r"
trait Display {
    fn display(self) -> String
}
";
    
    let result = eval_in_repl(code);
    // For now, trait definitions might not return anything or return a placeholder
    assert!(result.is_ok() || result.is_err(), "Trait definition should at least parse");
}

#[test]
fn test_trait_implementation() {
    // Test implementing a trait for a type
    let code = r#"
trait Display {
    fn display(self) -> String
}

struct Point { x: i32, y: i32 }

impl Display for Point {
    fn display(self) -> String {
        format!("Point({}, {})", self.x, self.y)
    }
}
"#;
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Trait implementation should at least parse");
}

#[test]
fn test_trait_method_call() {
    // Test calling trait methods
    let code = r#"
trait Display {
    fn display(self) -> String
}

struct Point { x: i32, y: i32 }

impl Display for Point {
    fn display(self) -> String {
        format!("Point({}, {})", self.x, self.y)
    }
}

let p = Point { x: 10, y: 20 }
p.display()
"#;
    
    let result = eval_in_repl(code);
    // This might fail initially as traits aren't implemented
    if let Ok(res) = result {
        assert!(res.contains("10") && res.contains("20"));
    }
}

#[test]
fn test_default_trait_methods() {
    // Test traits with default method implementations
    let code = r#"
trait Greet {
    fn name(self) -> String
    
    fn greet(self) -> String {
        format!("Hello, {}", self.name())
    }
}

struct Person { name: String }

impl Greet for Person {
    fn name(self) -> String {
        self.name
    }
}
"#;
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Default trait methods should at least parse");
}

#[test]
fn test_trait_bounds() {
    // Test generic functions with trait bounds
    let code = r"
trait Display {
    fn display(self) -> String
}

fn print_it<T: Display>(value: T) -> String {
    value.display()
}
";
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Trait bounds should at least parse");
}

#[test]
fn test_multiple_trait_implementations() {
    // Test implementing multiple traits for the same type
    let code = r#"
trait Display {
    fn display(self) -> String
}

trait Debug {
    fn debug(self) -> String
}

struct Point { x: i32, y: i32 }

impl Display for Point {
    fn display(self) -> String {
        format!("Point({}, {})", self.x, self.y)
    }
}

impl Debug for Point {
    fn debug(self) -> String {
        format!("Point {{ x: {}, y: {} }}", self.x, self.y)
    }
}
"#;
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Multiple trait implementations should at least parse");
}

#[test]
fn test_derive_traits() {
    // Test deriving common traits
    let code = r"
#[derive(Debug, Clone, PartialEq)]
struct Point { x: i32, y: i32 }
";
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Derive syntax should at least parse");
}

#[test]
fn test_associated_types() {
    // Test traits with associated types
    let code = r"
trait Iterator {
    type Item
    fn next(self) -> Option<Self::Item>
}
";
    
    let result = eval_in_repl(code);
    assert!(result.is_ok() || result.is_err(), "Associated types should at least parse");
}