#!/usr/bin/env perl
# Create all templates in the examples/templates directory

use warnings;
use strict;
use feature 'say';

use Log::Report;
use File::Slurper  qw(read_lines write_text);

use lib 'lib';
use Business::CAMT ();

use Data::Dumper;
$Data::Dumper::Indent    = 1; 
$Data::Dumper::Quotekeys = 0; 
$Data::Dumper::Sortkeys  = 1; 

my $xsddir  = 'lib/Business/CAMT/xsd';
my $tagdir  = 'lib/Business/CAMT/tags';
my $urnbase = 'urn:iso:std:iso:20022:tech:xsd';

my $templs  = 'templates';
-d $templs or mkdir $templs or fault $templs;

my $templs2  = 'templates-long';
-d $templs2 or mkdir $templs2 or fault $templs2;

#
## Create templates with abbreviations
#

say "Creating templates with abbreviated tags.";
my $camt    = Business::CAMT->new;
my %abbrevs;

foreach my $version ($camt->knownVersions)
{	my $schema = "$xsddir/$version.xsd";
	$camt->schemas->importDefinitions($schema);

	my $ns   = "$urnbase:$version";
	my $dump = $camt->schemas->template(PERL => "{$ns}Document");

	my $fn   = "$templs/$version.dd";
	if(! -f $fn || -M $schema < -M $fn)
	{	say " - creating/updating $version";
		open my $fh, '>:encoding(UTF-8)', $fn or fault $fn;
		$fh->print($dump);
		$fh->close;
	}

	$abbrevs{$_}++ for $dump =~ /^\s*(\w+)\s+\=\>/gm;
}

delete $abbrevs{$_} for qw/_ ANY/;

#
## Detect missing abbreviations
#

say "Build long_tagnames index";
say "- detected unique tags: " . keys %abbrevs;

my %umltags = reverse map split(/\,/, $_, 2),
	read_lines "$tagdir/abbreviations.csv";

#warn Dumper \%umltags;

say "- UML list of abbreviations: " . keys %umltags;

my %index;
foreach my $abbrev (keys %abbrevs)
{	if(my $long = $umltags{$abbrev})
	{	$index{$abbrev} = $long;
	}
}

say "- used UML abbreviations: " . keys %index;
say "- unused UML abbreviations: " , (keys %umltags) - (keys %index);

my %current = map split(/,/, $_, 2), read_lines "$tagdir/index.csv";

say "- please remove tag: $_"
	for grep !$abbrevs{$_}, sort keys %current;

say "- UML defines $_ as $index{$_}, overruled as $current{$_}"
	for grep $current{$_} && $index{$_} && $current{$_} ne $index{$_}, sort keys %current;

my @added = grep !exists $current{$_}, keys %abbrevs;

if(@added)
{   $current{$_} ||= $umltags{$_} || '' for @added;

	say "- updating index file.";
    write_text "$tagdir/index.csv", join '',
	    map "$_,$current{$_}\n", sort keys %current;
}

say "- missing long names: " . (grep $_ eq '', values %current);

#
## Create templates with long names
#

say "Creating templates with full size tags.";
my $camt2    = Business::CAMT->new(long_tagnames => 1);

foreach my $version ($camt2->knownVersions)
{	my $schema = "$xsddir/$version.xsd";
	$camt2->schemas->importDefinitions($schema);

 	my $ns   = "$urnbase:$version";
	my $fn   = "$templs2/$version.dd";

	if(! -f $fn || -M $schema < -M $fn)
	{	say " - creating/updating $fn";
		open my $fh, '>:encoding(UTF-8)', $fn or fault $fn;

		$fh->print($camt2->schemas->template(PERL => "{$ns}Document",
        	key_rewrite   => $camt2->tag2fullnameTable,
		));
		$fh->close;
	}

}

exit 0
