use chumsky::{primitive::just, IterParser, Parser};

use crate::{
    __internal__parse_include_str, __internal__span_macro_include_str,
    ast::{Expression, Literal, MemberAccess, StringLiteralComponent},
    parse::source_file::expression::expression,
};

use pretty_assertions::assert_eq;

#[test]
fn test_parse_control_flow() {
    __internal__span_macro_include_str!(
        crate::Span,
        "../../../../../../testdata/partial/controlflow.cctmpl"
    );

    assert_eq!(
        __internal__parse_include_str!(
            expression()
                .separated_by(just(";").padded())
                .allow_trailing()
                .collect::<Vec<Expression>>(),
            "../../../../../../testdata/partial/controlflow.cctmpl"
        )
        .unwrap(),
        vec![
            Expression::If {
                condition: (Box::new(Expression::Literal(Literal::Bool(true))), s!(3..7)),
                then_expression: (
                    Box::new(Expression::Literal(Literal::String(vec![(
                        StringLiteralComponent::Literal("Very true!"),
                        s!(9..19)
                    )]))),
                    s!(8..20)
                ),
                else_expression: None
            },
            Expression::If {
                condition: (
                    Box::new(Expression::Literal(Literal::Bool(true))),
                    s!(25..29)
                ),
                then_expression: (Box::new(Expression::Literal(Literal::Int(1))), s!(30..31)),
                else_expression: Some((Box::new(Expression::Literal(Literal::Int(0))), s!(37..38)))
            },
            Expression::Each {
                variable: ("test", s!(45..49)),
                array_expression: (Box::new(Expression::VariableOrCall("tests")), s!(53..58)),
                body_expression: (
                    Box::new(Expression::Call {
                        func: (Box::new(Expression::VariableOrCall("run")), s!(60..63)),
                        arguments: vec![(Expression::VariableOrCall("test"), s!(64..68))],
                    }),
                    s!(59..69)
                )
            },
            Expression::If {
                condition: (
                    Box::new(Expression::MemberAccess {
                        expression: (Box::new(Expression::VariableOrCall("signal")), s!(74..80)),
                        access: (MemberAccess::Named("recent", s!(81..87)), s!(80..87))
                    }),
                    s!(74..87)
                ),
                then_expression: (
                    Box::new(Expression::Literal(Literal::String(vec![(
                        StringLiteralComponent::Literal("Recent signal"),
                        s!(89..102)
                    )]))),
                    s!(88..103)
                ),
                else_expression: Some((
                    Box::new(Expression::Literal(Literal::String(vec![(
                        StringLiteralComponent::Literal("Signal"),
                        s!(110..116)
                    ),]))),
                    s!(109..117)
                ))
            }
        ]
    );
}
