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

use crate::{
    __internal__parse_include_str, __internal__parse_with_path, __internal__span_macro_include_str,
    __internal__span_macro_with_path,
    ast::{IndentationMarker, Template, TemplateBody, Type},
    parse::source_file::{
        expression::expression,
        template::{parameters, template},
    },
};

use pretty_assertions::assert_eq;

#[test]
fn test_parse_parameters() {
    {
        __internal__span_macro_with_path!(crate::Span, "<test>", "(indentation:int)");

        assert_eq!(
            __internal__parse_with_path!(parameters(), "<test>", "(indentation:int)").unwrap(),
            vec![(
                ("indentation", s!(1..12)),
                (Some(Type::Ident("int")), s!(13..16))
            )]
        );
    }
    {
        __internal__span_macro_with_path!(
            crate::Span,
            "<test>",
            "( // comments galore!\nindentation /* here too */: // and here\nint  )"
        );

        assert_eq!(
            __internal__parse_with_path!(
                parameters(),
                "<test>",
                "( // comments galore!\nindentation /* here too */: // and here\nint  )"
            )
            .unwrap(),
            vec![(
                ("indentation", s!(22..33)),
                (Some(Type::Ident("int")), s!(62..65))
            )]
        );
    }
}

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

    assert_eq!(
        __internal__parse_include_str!(
            template(expression())
                .separated_by(newline())
                .allow_trailing()
                .collect::<Vec<Template>>(),
            "../../../../../testdata/partial/template_definitions.cctmpl"
        )
        .unwrap(),
        vec![
            Template {
                output_type: (None, s!(0..0)),
                name: ("no_arguments", s!(9..21)),
                parameters: vec![],
                body: TemplateBody {
                    indentation_marker: IndentationMarker::None,
                    lines: vec![]
                }
            },
            Template {
                output_type: (Some("text"), s!(28..32)),
                name: ("greet", s!(42..47)),
                parameters: vec![(("name", s!(48..52)), (None, s!(52..52)))],
                body: TemplateBody {
                    indentation_marker: IndentationMarker::None,
                    lines: vec![]
                }
            },
            Template {
                output_type: (Some("html"), s!(60..64)),
                name: ("greet_explicit_type", s!(74..93)),
                parameters: vec![(
                    ("name", s!(94..98)),
                    (Some(Type::Ident("text")), s!(100..104))
                )],
                body: TemplateBody {
                    indentation_marker: IndentationMarker::None,
                    lines: vec![]
                }
            },
            Template {
                output_type: (None, s!(114..114)),
                name: ("whacky", s!(151..157)),
                parameters: vec![(
                    ("indentation", s!(231..242)),
                    (Some(Type::Ident("int")), s!(271..274))
                )],
                body: TemplateBody {
                    indentation_marker: IndentationMarker::None,
                    lines: vec![]
                }
            }
        ]
    );
}
