use std::path::PathBuf;

use prune_lang::cli;

#[test]
fn test_append_good() {
    let res = cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_good/append_good.pr"))
        .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

#[test]
fn test_append_bad() {
    let res = cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_bad/append_bad.pr"))
        .unwrap();
    assert!(res.iter().any(|p| *p > 0));
}

#[test]
fn test_double_reverse_good() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_good/double_reverse_good.pr",
    ))
    .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

#[test]
fn test_double_reverse_bad() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_bad/double_reverse_bad.pr",
    ))
    .unwrap();
    assert!(res.iter().any(|p| *p > 0));
}

#[test]
fn test_reverse_length_good() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_good/reverse_length_good.pr",
    ))
    .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

#[test]
fn test_reverse_length_bad() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_bad/reverse_length_bad.pr",
    ))
    .unwrap();
    assert!(res.iter().any(|p| *p > 0));
}

#[test]
fn test_tree_insert_good() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_good/tree_insert_good.pr",
    ))
    .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

#[test]
fn test_tree_insert_bad() {
    let res =
        cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_bad/tree_insert_bad.pr"))
            .unwrap();
    assert!(res.iter().any(|p| *p > 0));
}

#[test]
fn test_avl_tree_good() {
    let res =
        cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_good/avl_tree_good.pr"))
            .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

// #[test]
// fn test_avl_tree_bad() {
//     let res = cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_bad/avl_tree_bad.pr"))
//         .unwrap();
//     assert!(res.iter().any(|p| *p > 0));
// }

#[test]
fn test_avl_tree_opt_good() {
    let res = cli::pipeline::run_cli_test(PathBuf::from(
        "./examples/sym_exec_good/avl_tree_opt_good.pr",
    ))
    .unwrap();
    assert!(res.iter().all(|p| *p == 0));
}

// #[test]
// fn test_avl_tree_opt_bad() {
//     let res =
//         cli::pipeline::run_cli_test(PathBuf::from("./examples/sym_exec_bad/avl_tree_opt_bad.pr"))
//             .unwrap();
//     assert!(res.iter().any(|p| *p > 0));
// }

#[test]
fn test_avl_tree_gen() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/test_gen/avl_tree_gen.pr")).unwrap();
}

#[test]
fn test_avl_tree_opt_gen() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/test_gen/avl_tree_opt_gen.pr")).unwrap();
}

#[test]
fn test_lambda_free_gen() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/test_gen/lambda_free_gen.pr")).unwrap();
}

#[test]
fn test_stlc_term_gen() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/test_gen/stlc_term_gen.pr")).unwrap();
}

#[test]
fn test_mini_lang_gen() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/test_gen/mini_lang_gen.pr")).unwrap();
}

#[test]
fn test_reverse_forward() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/basic/reverse_forward.pr")).unwrap();
}

#[test]
fn test_reverse_backward() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/basic/reverse_backward.pr")).unwrap();
}

#[test]
fn test_concat_forward() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/basic/concat_forward.pr")).unwrap();
}

#[test]
fn test_concat_backward() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/basic/concat_backward.pr")).unwrap();
}

#[test]
fn test_pythagorean() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/other/pythagorean.pr")).unwrap();
}

#[test]
fn test_fermat_n3() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/other/fermat_n3.pr")).unwrap();
}

#[test]
fn test_unary_arith() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/arith/unary_arith.pr")).unwrap();
}

#[test]
fn test_binary_arith() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/arith/binary_arith.pr")).unwrap();
}

#[test]
fn test_polymorphism() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/features/polymorphism.pr")).unwrap();
}

#[test]
fn test_polymorphism_fail() {
    cli::pipeline::run_cli_test(PathBuf::from("./examples/features/polymorphism_fail.pr"))
        .expect_err("this should fail at type checking!");
}
