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

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

use pretty_assertions::assert_eq;

#[test]
#[allow(clippy::too_many_lines)]
fn test_parse_literals() {
    __internal__span_macro_include_str!(
        crate::Span,
        "../../../../../../testdata/partial/literals.cctmpl"
    );

    assert_eq!(
        __internal__parse_include_str!(
            literal(expression())
                .then_ignore(just(";"))
                .separated_by(newline())
                .allow_trailing()
                .collect::<Vec<Literal>>(),
            "../../../../../../testdata/partial/literals.cctmpl"
        )
        .unwrap(),
        vec![
            Literal::String(vec![(
                StringLiteralComponent::Literal("Hello World!"),
                s!(1..13)
            )]),
            Literal::String(vec![
                (StringLiteralComponent::Literal("Hello"), s!(17..22)),
                (
                    StringLiteralComponent::EscapeSequence(EscapeSequence::Newline),
                    s!(22..24)
                ),
                (StringLiteralComponent::Literal("World!"), s!(24..30))
            ]),
            Literal::String(vec![
                (StringLiteralComponent::Literal("Hello "), s!(34..40)),
                (
                    StringLiteralComponent::EscapeSequence(EscapeSequence::Backslash),
                    s!(40..42)
                ),
                (StringLiteralComponent::Literal(" World!"), s!(42..49))
            ]),
            Literal::String(vec![
                (StringLiteralComponent::Literal("Hello"), s!(53..58)),
                (
                    StringLiteralComponent::EscapeSequence(EscapeSequence::Tab),
                    s!(58..60)
                ),
                (StringLiteralComponent::Literal("World!"), s!(60..66))
            ]),
            Literal::String(vec![
                (StringLiteralComponent::Literal("Hello "), s!(70..76)),
                (StringLiteralComponent::EscapedQuote, s!(76..78)),
                (StringLiteralComponent::Literal("World"), s!(78..83)),
                (StringLiteralComponent::EscapedQuote, s!(83..85)),
                (StringLiteralComponent::Literal("!"), s!(85..86))
            ]),
            Literal::String(vec![
                (StringLiteralComponent::Literal("Hello "), s!(90..96)),
                (
                    StringLiteralComponent::EscapeSequence(EscapeSequence::CarriageReturn),
                    s!(96..98)
                ),
                (StringLiteralComponent::Literal(" World!"), s!(98..105))
            ]),
            Literal::String(vec![]),
            Literal::Int(153),
            Literal::Int(-1223),
            Literal::Int(123),
            Literal::Bool(true),
            Literal::Bool(false),
            Literal::Tuple(vec![(Expression::Literal(Literal::Int(1)), s!(145..146))]),
            Literal::Tuple(vec![
                (Expression::Literal(Literal::Int(1)), s!(151..152)),
                (Expression::Literal(Literal::Int(2)), s!(154..155)),
                (Expression::Literal(Literal::Int(3)), s!(157..158))
            ]),
            Literal::Array(vec![
                (
                    Expression::Literal(Literal::String(vec![(
                        StringLiteralComponent::Literal("Peter"),
                        s!(163..168)
                    )])),
                    s!(162..169)
                ),
                (
                    Expression::Literal(Literal::String(vec![(
                        StringLiteralComponent::Literal("Josh"),
                        s!(172..176)
                    )])),
                    s!(171..177)
                )
            ]),
            Literal::Struct(vec![
                (
                    ("name", s!(181..185)),
                    (
                        Expression::Literal(Literal::String(vec![(
                            StringLiteralComponent::Literal("Peter"),
                            s!(188..193)
                        )])),
                        s!(187..194)
                    )
                ),
                (
                    ("age", s!(196..199)),
                    (Expression::Literal(Literal::Int(21)), s!(201..203))
                )
            ]),
            Literal::Float(33.3),
            Literal::Float(-0.4),
            Literal::Float(0.004)
        ]
    );
}
