### ----------------------------------------------------
### -- Terminal::WCWidth
### -- Licenses: MIT
### -- Authors: +merlan #flirora, José Joaquín Atria, Raku Community
### -- File: tools/build.raku
### ----------------------------------------------------
#!/usr/bin/env raku

use HTTP::UserAgent;

constant TARGET = 'lib/Terminal/WCWidth/Tables.rakumod';

my $ua = HTTP::UserAgent.new;

sub get-cached ( $url, $target = $url.IO.basename --> Str ) {
    return $target if $target.IO.e;

    do given $ua.get($url) {
        die .status-line unless .is-success;

        spurt $target, .content;
        $target;
    }
}

sub parse ( $haystack, $needle ) {
    my ( $source, $date, @values );

    for $haystack.IO.lines -> $line {
        $source //= $/<source> if $line ~~ / '# ' $<source> = .+ /;
        $date   //= $/<date>   if $line ~~ / '# Date: ' $<date> = .+ /;

        next if $line.starts-with: '#';

        # START..END;PROP
        #     or
        # START;PROP
        next unless $line ~~ / ( (\w+)+ % '..' )+ % [ \s* ';' \s* ] /;

        my $prop = $/[ 0; 1 ];
        my ( $start, $end ) = |$/[ 0; 0; 0 ];

        next unless $prop && $prop ~~ $needle;

        $end //= $start;

        @values.push: ( ~$start, ~$end )».parse-base(16);
    }

    die "Did not parse any values from $haystack" unless @values;

    ( $date, $source, @values.sort )
}

sub make-table ( $path, $variable, $date, $source, @values ) {
    with $path.IO {
        my $fh will leave { .close } = .open: :ra;

        $fh.say: $_ for (
            '',
            "# Generated: { INIT now.DateTime }",
            "# Source: $source",
            "# Date: $date",
            "constant $variable is export = ("
        );

        for @values -> ( $start, $end ) {
            my $line = sprintf(
                 "(0x%04x, 0x%04x,),  # %-24.24s..%-.24s",
                $start,
                $end,
                $start.uniname.wordcase,
                $end.uniname.wordcase,
            );

            $fh.say: '    ' ~ $line.trim
        }

        $fh.say: ");";
    }
}

sub work ( $url, $var, $needle ) {
    my $path = get-cached( 'http://www.unicode.org/Public/UNIDATA/' ~ $url  );
    my ( $date, $source, $values ) = parse( $path, $needle );
    make-table( TARGET, $var, $date, $source, @$values );
}

sub MAIN () {
    spurt TARGET, q:to/HEADER/;
        unit module Terminal::WCWidth::Tables;

        # Generated by tools/build.raku
        HEADER

    work( 'extracted/DerivedGeneralCategory.txt', 'ZERO_WIDTH',     rx/ 'Me' || 'Mn' / );
    work(           'EastAsianWidth.txt',         'WIDE_EASTASIAN', rx/ 'W'  || 'F'  / );
}

# vim: expandtab shiftwidth=4


