
package Commods;
use IO::File;

use strict;
use warnings;

BEGIN {
    use Exporter ();
    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
    $VERSION     = 1.00;
    @ISA         = qw(Exporter);
    @EXPORT      = qw(&parse_masters %oceans %commods %clients
		      &parse_pctb_commodmap %pctb_commodmap @pctb_commodmap
		      &get_our_version);
    %EXPORT_TAGS = ( );

    @EXPORT_OK   = qw();
}

our %oceans; # eg $oceans{'Midnight'}{'Ruby'}{'Eta Island'}= $sources;
our %commods; # eg $commods{'Fine black cloth'}= $sources;
our %clients; # eg $clients{'ypp-sc-tools'}= [ qw(last-page) ];
# $sources = 's[l]b';
#       's' = Special Circumstances; 'l' = local ; B = with Bleach

our (%pctb_commodmap,@pctb_commodmap);

my %colours; # eg $colours{'c'}{'black'}= $sources
my @rawcm; # eg $rawcm[0]='fine rum'; $rawcm[1]='fine %c cloth'

sub parse_master_master1 ($$) {
    my ($mmfn,$src)= @_;
    my $mm= new IO::File $mmfn, 'r' or die "$mmfn $!";
    my @ctx= ();
    while (<$mm>) {
	next if m/^\s*\#/;
	next unless m/\S/;
	s/\s+$//;
	if (m/^\%(\w+)$/) {
	    my $colourkind= $1;
	    @ctx= (sub { $colours{$colourkind}{lc $_} .= $src; });
	} elsif (m/^commods$/) {
	    @ctx= (sub { push @rawcm, lc $_; });
	} elsif (m/^ocean (\w+)$/) {
	    my $ocean= $1;
	    @ctx= (sub {
		$ocean or die; # ref to $ocean needed to work
		               # around a perl bug
		my $arch= $_;
		$ctx[1]= sub {
		    $oceans{$ocean}{$arch}{$_} .= $src;
		};
	    });
	} elsif (m/^client (\S+.*\S)$/) {
	    my $client= $1;
	    $clients{$client}= [ ];
	    @ctx= (sub {
		my $bug= $_;
		push @{ $clients{$client} }, $bug;
	    });
	} elsif (s/^ +//) {
	    my $indent= length $&;
	    die "wrong indent $indent" unless defined $ctx[$indent-1];
	    &{ $ctx[$indent-1] }();
	} else {
	    die "bad syntax";
	}
    }
    $mm->error and die $!;
    close $mm or die $!;

#print Dumper(\%oceans);
#print Dumper(\@rawcm);
	
    %commods= ();
    my $ca;
    $ca= sub {
	my ($s,$ss) = @_;
#print "ca($s)\n";
	if ($s !~ m/\%(\w+)/) { $commods{ucfirst $s} .= $ss; return; }
	die "unknown $&" unless defined $colours{$1};
	foreach my $c (keys %{ $colours{$1} }) {
	    &$ca($`.$c.$', $ss .'%'. $colours{$1}{$c});
	}
    };
    foreach (@rawcm) { &$ca($_,$src); }
}

sub parse_masters () {
    parse_master_master1('master-master.txt','s');
}

sub parse_pctb_commodmap () {
    undef %pctb_commodmap;
    foreach my $commod (keys %commods) { $commods{$commod} =~ s/b//; }

    my $c= new IO::File '_commodmap.tsv' or die $!;
    if (!$c) { $!==&ENOENT or die $!; return 0; }

    while (<$c>) {
	m/^(\S.*\S)\t(\d+)\n$/ or die "$_";
	die if defined $pctb_commodmap{$1};  $pctb_commodmap{$1}= $2;
	die if defined $pctb_commodmap[$2];  $pctb_commodmap[$2]= $1;
	$commods{$1} .= 'b';
    }
    $c->error and die $!;
    close $c or die $!;
    return 1;
}

sub get_our_version ($) {
    my ($prefix);
    {
	no strict (qw(refs));
	${ "${prefix}name"  }= 'ypp-sc-tools yarrg';
        ${ "${prefix}fixes" }= 'lastpage';
        ${ "${prefix}version" }= `git-describe --tags HEAD`;
        $? and die $?;
    }
}

1;
