use v6.d;
use Test;
use Test::Output;
use RakuDoc::Templates;

plan 22;
# All the templates here return Str, so no need to worry about premature stringification.

my %template-dir is Template-directory = %(
    aaa => -> %prm, $tmpl {
        'orig: ' ~ %prm<contents>;
    },
    bbb => -> %prm, $tmpl { '<bb-aaa-tab>' ~ $tmpl('aaa') ~ '</end-tab>' },
    ccc => -> %prm, $tmpl { '<cc-aaa-tab>' ~ $tmpl('aaa', %(:contents('never'),)) ~ '</end-tab>' },
    ddd => -> %prm, $tmpl { 'stuff ' ~ $tmpl('head') ~ ' more' },
    eee => -> %prm, $tmpl { 'try something ' ~ $tmpl.prev ~ 'new' },
    fff => -> %prm, $tmpl { '<bb-aaa-tab>' ~ $tmpl<aaa> ~ '</end-tab>' },
    ggg => -> %prm, $tmpl { '<start>' ~ %prm<contents> ~ '<end>' }
);
is %template-dir<aaa>(%(:contents<hi there>)), 'orig: hi there', 'simple interpolation';
is %template-dir<bbb>(%(:contents<bold statement>,)), '<bb-aaa-tab>orig: bold statement</end-tab>',
        'call another template with same params';
is %template-dir<fff>(%(:contents<bold statement>,)), '<bb-aaa-tab>orig: bold statement</end-tab>', 'calls another template with <> with same parameters';
is %template-dir<ccc>(%()), '<cc-aaa-tab>orig: never</end-tab>', 'calls another template with different 0 parameters';

%template-dir.debug = True;
my $rv;
output-like { $rv = %template-dir<aaa>(%(:contents<hi there>)) },
        / 'Template' .+ 'aaa' .+ 'source: Initial' /,
        'debug generates information about the template';
is $rv, 'orig: hi there', 'debug & simple interpolation';
output-like { $rv = %template-dir<bbb>(%(:contents<bold statement>,)) },
        / 'Template' .+ 'bbb' .+ 'source: Initial' .+
        'Embedded' .+ 'aaa' .+ 'stored params' .+
        'Template' .+ 'aaa' .+ 'source: Initial' /,
        'debug generates information about the template called and those called inside template';
is $rv, '<bb-aaa-tab>orig: bold statement</end-tab>',
        'debug & call another template with same params';
output-like { $rv = %template-dir<ccc>(%()), '<cc-aaa-tab>orig: never</end-tab>' },
        /  'Template' .+ 'ccc' .+ 'source: Initial' .+
        'Embedded' .+ 'aaa' .+ 'new params' .+
        'Template' .+ 'aaa' .+ 'source: Initial' /,
        'debug indicates new parameters are used';
is $rv, '<cc-aaa-tab>orig: never</end-tab>', 'debug & calls another template with different 0 parameters';

%template-dir.debug = False;
%template-dir.source = 'Next test';

%template-dir<aaa> = -> %prm, $tmpl {
    qq:to/TMP/;
        <layer 1> { $tmpl.prev } </layer 1>
        TMP
};

is %template-dir<aaa>(%(:contents<now there>)), q:to/TST/, 'calls a previous template';
<layer 1> orig: now there </layer 1>
TST

%template-dir.debug = True;
output-like { $rv = %template-dir<aaa>(%(:contents<now there>)) },
    / 'Template' .+ 'aaa' .+ 'source: Next test' /,
    'use of previous with debug';
is $rv, q:to/TST/, 'debug & calls a previous template';
<layer 1> orig: now there </layer 1>
TST

%template-dir.debug = False;
%template-dir.source = 'Second level test';
%template-dir<aaa> = -> %prm, $tmpl {
    qq:to/TMP/;
        <layer 2> { $tmpl.prev } </layer 2>
        TMP
};
is %template-dir<aaa>(%(:contents<let this be now>)), q:to/TST/, 'calls a previous, previous template';
<layer 2> <layer 1> orig: let this be now </layer 1>
 </layer 2>
TST

%template-dir.debug = True;
output-like { $rv = %template-dir<aaa>(%(:contents<let this be now>))},
    / 'Template' .+ 'aaa' .+ 'source: Second level test' /,
    'two levels of previous templates';
is $rv, q:to/TST/, 'debug & calls a previous, previous template';
<layer 2> <layer 1> orig: let this be now </layer 1>
 </layer 2>
TST

%template-dir.debug = False;
throws-like { %template-dir<head>(%(:contents<hi there>)) }, X::Unexpected-Template,
        message => / 'Template ｢head｣ is not known' /, 'try to call unregistered template';
throws-like { %template-dir<ddd>(%(:contents<hi there>)) }, X::Unexpected-Template,
        message => / 'Template ｢head｣ is not known' /, 'try to call unregistered template inside another templ';

is %template-dir<eee>( %() ), 'try something new', 'calls .prev for end of a stack';

%template-dir<ggg> = -> %prm, $tmpl { %prm<contents> = 'Chapter ' ~ %prm<contents> ; $tmpl.prev( %prm ) }
is %template-dir<ggg>(%(:contents<Some stuff>)), '<start>Chapter Some stuff<end>', 'pre processing for a prev template';

%template-dir.test = True;
is %template-dir<ggg>(%( :contents<Some stuff>, :caption<A caption> ) ),
    "<ggg>\ncaption: ｢A caption｣\ncontents: ｢Some stuff｣\n</ggg>\n",
    'test of template only returns its parameters';
$rv = %template-dir<aaa>(%(:contents<something>, ggg => %template-dir<ggg>(%(:contents<more stiff>,)),));
is $rv,
    "<aaa>\ncontents: ｢something｣\nggg: ｢<ggg>\ncontents: ｢more stiff｣\n</ggg>\n｣\n</aaa>\n",
    'test of parameters with embedded template';
### TODO test the new pretty flag
done-testing;
