use gonidium::{Value, interp_eval, lower, parse_dsl};

#[test]
fn full_pipeline_add() {
    let text = r#"
    |a: f64, b: f64|
    a + b
    "#;
    let func = parse_dsl(text).expect("parse should succeed");
    let dag = lower(&func).expect("lower should succeed").dag;
    let out =
        interp_eval(&dag, &[Value::F64(1.0), Value::F64(2.0)]).expect("interp should succeed");
    assert_eq!(out, vec![Value::F64(3.0)]);
}

#[test]
fn full_pipeline_let_chain() {
    let text = r#"
    |x: f64|
    t = x * 2
    t + 1
    "#;
    let func = parse_dsl(text).expect("parse should succeed");
    let dag = lower(&func).expect("lower should succeed").dag;
    let out = interp_eval(&dag, &[Value::F64(2.0)]).expect("interp should succeed");
    assert_eq!(out, vec![Value::F64(5.0)]);
}

#[test]
fn full_pipeline_if_else() {
    let text = r#"
    |x: f64|
    if x > 0 then x else -x
    "#;
    let func = parse_dsl(text).expect("parse should succeed");
    let dag = lower(&func).expect("lower should succeed").dag;
    let out1 = interp_eval(&dag, &[Value::F64(3.0)]).expect("interp should succeed");
    let out2 = interp_eval(&dag, &[Value::F64(-3.0)]).expect("interp should succeed");
    assert_eq!(out1, vec![Value::F64(3.0)]);
    assert_eq!(out2, vec![Value::F64(3.0)]);
}

#[test]
fn full_pipeline_builtin_call() {
    let text = r#"
    |x: f64|
    exp(x)
    "#;
    let func = parse_dsl(text).expect("parse should succeed");
    let dag = lower(&func).expect("lower should succeed").dag;
    let out = interp_eval(&dag, &[Value::F64(0.0)]).expect("interp should succeed");
    assert_eq!(out, vec![Value::F64(1.0)]);
}

#[test]
fn full_pipeline_floor_ceil_calls() {
    let floor_text = r#"
    |x: f64|
    floor(x)
    "#;
    let floor_func = parse_dsl(floor_text).expect("parse should succeed");
    let floor_dag = lower(&floor_func).expect("lower should succeed").dag;
    let floor_out = interp_eval(&floor_dag, &[Value::F64(1.9)]).expect("interp should succeed");
    assert_eq!(floor_out, vec![Value::F64(1.0)]);

    let ceil_text = r#"
    |x: f64|
    ceil(x)
    "#;
    let ceil_func = parse_dsl(ceil_text).expect("parse should succeed");
    let ceil_dag = lower(&ceil_func).expect("lower should succeed").dag;
    let ceil_out = interp_eval(&ceil_dag, &[Value::F64(1.1)]).expect("interp should succeed");
    assert_eq!(ceil_out, vec![Value::F64(2.0)]);
}
