// SIMPLE COVERAGE BOOST - Compilable tests for immediate coverage gain
// Sprint 80 CONTINUATION: Push from 70.25% to 75%+

use ruchy::backend::transpiler::Transpiler;
use ruchy::frontend::ast::*;
use ruchy::frontend::lexer::{Lexer, Token};
use ruchy::runtime::{Environment, Value};

#[test]
fn test_lexer_tokenize_numbers() {
    let mut lexer = Lexer::new("42 3.14 0xFF 0b1010");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_lexer_tokenize_strings() {
    let mut lexer = Lexer::new(r#""hello" "world" "escaped\n""#);
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_lexer_tokenize_operators() {
    let mut lexer = Lexer::new("+ - * / % ** == != < > <= >=");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_lexer_tokenize_keywords() {
    let mut lexer = Lexer::new("let mut fn if else while for match");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_lexer_tokenize_delimiters() {
    let mut lexer = Lexer::new("( ) [ ] { } , ; : . .. ..=");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_token_display() {
    let token = Token::Integer(42);
    let _ = format!("{:?}", token);
    let token = Token::Float(3.14);
    let _ = format!("{:?}", token);
    let token = Token::String("test".to_string());
    let _ = format!("{:?}", token);
}

#[test]
fn test_ast_expr_creation() {
    let expr = Expr {
        kind: ExprKind::Literal(Literal::Integer(42)),
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::Literal(_)));
}

#[test]
fn test_ast_binary_ops() {
    let ops = vec![
        BinaryOp::Add,
        BinaryOp::Sub,
        BinaryOp::Mul,
        BinaryOp::Div,
        BinaryOp::Mod,
        BinaryOp::Pow,
        BinaryOp::Eq,
        BinaryOp::Ne,
        BinaryOp::Lt,
        BinaryOp::Gt,
        BinaryOp::Le,
        BinaryOp::Ge,
        BinaryOp::And,
        BinaryOp::Or,
    ];
    for op in ops {
        let _ = format!("{:?}", op);
    }
}

#[test]
fn test_ast_unary_ops() {
    let ops = vec![UnaryOp::Neg, UnaryOp::Not];
    for op in ops {
        let _ = format!("{:?}", op);
    }
}

#[test]
fn test_ast_literals() {
    let literals = vec![
        Literal::Unit,
        Literal::Integer(42),
        Literal::Float(3.14),
        Literal::String("test".to_string()),
        Literal::Char('a'),
        Literal::Bool(true),
        Literal::Bool(false),
    ];
    for lit in literals {
        let _ = format!("{:?}", lit);
    }
}

#[test]
fn test_ast_patterns() {
    let patterns = vec![
        Pattern::Wildcard,
        Pattern::Identifier("x".to_string()),
        Pattern::Literal(Literal::Integer(42)),
        Pattern::Tuple(vec![]),
        Pattern::List(vec![], None),
        Pattern::Rest(None),
    ];
    for pat in patterns {
        let _ = format!("{:?}", pat);
    }
}

#[test]
fn test_value_creation() {
    let values = vec![
        Value::Unit,
        Value::Integer(42),
        Value::Float(3.14),
        Value::Bool(true),
        Value::String(std::rc::Rc::new("test".to_string())),
    ];
    for val in values {
        let _ = format!("{:?}", val);
    }
}

#[test]
fn test_value_equality() {
    assert_eq!(Value::Integer(42), Value::Integer(42));
    assert_ne!(Value::Integer(42), Value::Integer(43));
    assert_eq!(Value::Bool(true), Value::Bool(true));
    assert_ne!(Value::Bool(true), Value::Bool(false));
}

#[test]
fn test_value_display() {
    let val = Value::Integer(42);
    assert_eq!(format!("{}", val), "42");
    let val = Value::Bool(true);
    assert_eq!(format!("{}", val), "true");
    let val = Value::Unit;
    assert_eq!(format!("{}", val), "()");
}

#[test]
fn test_environment_creation() {
    let env = Environment::new();
    assert!(env.lookup("undefined").is_none());
}

#[test]
fn test_environment_define() {
    let mut env = Environment::new();
    env.define("x", Value::Integer(42), false);
    assert_eq!(env.lookup("x"), Some(&Value::Integer(42)));
}

#[test]
fn test_environment_mutable() {
    let mut env = Environment::new();
    env.define("x", Value::Integer(42), true);
    env.set("x", Value::Integer(43));
    assert_eq!(env.lookup("x"), Some(&Value::Integer(43)));
}

#[test]
fn test_environment_scopes() {
    let mut env = Environment::new();
    env.define("x", Value::Integer(42), false);
    env.push_scope();
    env.define("x", Value::Integer(43), false);
    assert_eq!(env.lookup("x"), Some(&Value::Integer(43)));
    env.pop_scope();
    assert_eq!(env.lookup("x"), Some(&Value::Integer(42)));
}

#[test]
fn test_transpiler_creation() {
    let transpiler = Transpiler::new();
    let _ = transpiler; // Use it
}

#[test]
fn test_transpiler_simple() {
    let transpiler = Transpiler::new();
    let expr = Expr {
        kind: ExprKind::Literal(Literal::Integer(42)),
        span: Default::default(),
        attributes: vec![],
    };
    let rust_code = transpiler.transpile(&expr);
    assert_eq!(rust_code, "42");
}

#[test]
fn test_span_creation() {
    let span = Span::new(0, 10);
    assert_eq!(span.start, 0);
    assert_eq!(span.end, 10);
}

#[test]
fn test_span_default() {
    let span = Span::default();
    assert_eq!(span.start, 0);
    assert_eq!(span.end, 0);
}

// More Value tests
#[test]
fn test_value_list() {
    let list = Value::List(std::rc::Rc::new(vec![
        Value::Integer(1),
        Value::Integer(2),
        Value::Integer(3),
    ]));
    assert!(matches!(list, Value::List(_)));
}

#[test]
fn test_value_tuple() {
    let tuple = Value::Tuple(std::rc::Rc::new(vec![
        Value::Integer(1),
        Value::String(std::rc::Rc::new("hello".to_string())),
    ]));
    assert!(matches!(tuple, Value::Tuple(_)));
}

#[test]
fn test_value_object() {
    use std::collections::HashMap;
    let mut fields = HashMap::new();
    fields.insert("x".to_string(), Value::Integer(42));
    let obj = Value::Object(std::rc::Rc::new(fields));
    assert!(matches!(obj, Value::Object(_)));
}

// More AST tests
#[test]
fn test_expr_binary() {
    let expr = Expr {
        kind: ExprKind::Binary {
            left: Box::new(Expr {
                kind: ExprKind::Literal(Literal::Integer(1)),
                span: Default::default(),
                attributes: vec![],
            }),
            op: BinaryOp::Add,
            right: Box::new(Expr {
                kind: ExprKind::Literal(Literal::Integer(2)),
                span: Default::default(),
                attributes: vec![],
            }),
        },
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::Binary { .. }));
}

#[test]
fn test_expr_unary() {
    let expr = Expr {
        kind: ExprKind::Unary {
            op: UnaryOp::Neg,
            operand: Box::new(Expr {
                kind: ExprKind::Literal(Literal::Integer(42)),
                span: Default::default(),
                attributes: vec![],
            }),
        },
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::Unary { .. }));
}

#[test]
fn test_expr_identifier() {
    let expr = Expr {
        kind: ExprKind::Identifier("x".to_string()),
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::Identifier(_)));
}

#[test]
fn test_expr_block() {
    let expr = Expr {
        kind: ExprKind::Block(vec![]),
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::Block(_)));
}

#[test]
fn test_expr_if() {
    let expr = Expr {
        kind: ExprKind::If {
            condition: Box::new(Expr {
                kind: ExprKind::Literal(Literal::Bool(true)),
                span: Default::default(),
                attributes: vec![],
            }),
            then_branch: Box::new(Expr {
                kind: ExprKind::Literal(Literal::Integer(1)),
                span: Default::default(),
                attributes: vec![],
            }),
            else_branch: None,
        },
        span: Default::default(),
        attributes: vec![],
    };
    assert!(matches!(expr.kind, ExprKind::If { .. }));
}

// Test more patterns
#[test]
fn test_pattern_struct() {
    let pattern = Pattern::Struct {
        name: "Point".to_string(),
        fields: vec![],
        rest: false,
    };
    assert!(matches!(pattern, Pattern::Struct { .. }));
}

#[test]
fn test_pattern_or() {
    let pattern = Pattern::Or(vec![
        Pattern::Literal(Literal::Integer(1)),
        Pattern::Literal(Literal::Integer(2)),
    ]);
    assert!(matches!(pattern, Pattern::Or(_)));
}

#[test]
fn test_pattern_range() {
    let pattern = Pattern::Range {
        start: Some(Box::new(Pattern::Literal(Literal::Integer(1)))),
        end: Some(Box::new(Pattern::Literal(Literal::Integer(10)))),
        inclusive: false,
    };
    assert!(matches!(pattern, Pattern::Range { .. }));
}

// Test lexer edge cases
#[test]
fn test_lexer_empty_input() {
    let mut lexer = Lexer::new("");
    let tokens = lexer.tokenize().unwrap();
    assert_eq!(tokens.len(), 0);
}

#[test]
fn test_lexer_whitespace_only() {
    let mut lexer = Lexer::new("   \t\n\r  ");
    let tokens = lexer.tokenize().unwrap();
    assert_eq!(tokens.len(), 0);
}

#[test]
fn test_lexer_comments() {
    let mut lexer = Lexer::new("// comment\n42");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

#[test]
fn test_lexer_block_comments() {
    let mut lexer = Lexer::new("/* block comment */ 42");
    let tokens = lexer.tokenize().unwrap();
    assert!(tokens.len() > 0);
}

// Test more Value operations
#[test]
fn test_value_clone() {
    let val = Value::Integer(42);
    let cloned = val.clone();
    assert_eq!(val, cloned);
}

#[test]
fn test_value_debug() {
    let val = Value::Integer(42);
    let debug_str = format!("{:?}", val);
    assert!(debug_str.contains("Integer"));
}

// Test Environment edge cases
#[test]
fn test_environment_undefined_set() {
    let mut env = Environment::new();
    env.set("undefined", Value::Integer(42));
    // Should not crash
}

#[test]
fn test_environment_clear() {
    let mut env = Environment::new();
    env.define("x", Value::Integer(42), false);
    env.clear();
    assert!(env.lookup("x").is_none());
}

#[test]
fn test_environment_multiple_scopes() {
    let mut env = Environment::new();
    for i in 0..10 {
        env.push_scope();
        env.define(&format!("x{}", i), Value::Integer(i), false);
    }
    for _ in 0..10 {
        env.pop_scope();
    }
}
