### ----------------------------------------------------
### -- Text::Emoji
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: tools/make-emojis.raku
### ----------------------------------------------------
#!/usr/bin/env raku

# This script reads the lib/Text/Emoji.rakumod file, and generates the
# lookup Map in it.  It uses the currently available "emojis.json" file
# unless "update" is specified as a positional argument.

# always use highest version of Raku
use v6.*;

my $emojis-io := $*PROGRAM.parent(2).add("resources/emojis.json");
my @emojis;
my %reverse;
my $width;

my sub normalize(%map) {
    my @aliases;
    my $emoji := %map<emoji>;
    for %map<aliases><> -> $alias {
        $width max= $alias.chars;
        if $alias.contains('_') {
            my $hyphened := $alias.trans("_" => "-");
            my $cleaned  := $alias.trans("_" => "");
            @aliases.push: $hyphened => %map;
            @aliases.push: $cleaned  => %map;
            %reverse{$emoji}.push: $hyphened;
        }
        else {
            @aliases.push: $alias => %map;
            %reverse{$emoji}.push: $alias;
        }
    }
    @aliases.Slip
}

if @*ARGS.head -> $command {
    if $command eq 'update' {
        my $proc := run <curl https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json>, :out, :err;

        if $proc.exitcode -> $exitcode {
            if $proc.err.slurp -> $errors {
                note $errors;
            }
            else {
                note "Exited with: $exitcode";
            }
            exit 1;
        }
        
        if $proc.out.slurp -> $json {
            $emojis-io.spurt: $json;
            @emojis = Rakudo::Internals::JSON
              .from-json($json).map(&normalize).sort(*.key)
        }
        else {
            note "No emoji data obtained";
            exit 1;
        }
    }
    else {
        note "Don't know how to handle: @*ARGS";
        exit 1;
    }
}
else {
    @emojis = Rakudo::Internals::JSON
      .from-json($emojis-io.slurp).map(&normalize).sort(*.key);
}

# Make sure the shortest alternative is first
$_ = .sort(*.chars) for %reverse.values;

my $format := Format.new("  %-{$width}s'%s',\n");

my $generator = $*PROGRAM-NAME;
my $generated = DateTime.now.gist.subst(/\.\d+/,'');
my $start     = '#- start of generated part of Text::Emoji';
my $end       = '#- end of generated part of Text::Emoji';

# slurp the whole file and set up writing to it
my $file := $*PROGRAM.parent(2).add("lib/Text/Emoji.rakumod");
my @lines = $file.lines;  # must be greedy
$*OUT = $file.open(:w);

# for all the lines in the source that don't need special handling
while @lines {
    my $line := @lines.shift;

    # nothing to do yet
    unless $line.starts-with($start) {
        say $line;
        next;
    }

    say $start;
    say "#- Generated on $generated by $generator";
    say "#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE";

    # skip the old version of the code
    while @lines {
        last if @lines.shift.starts-with($end);
    }

    say "my constant %lookup =";
    print $format("'$_.key()',", .value<emoji>) for @emojis;
    say ";";

    say "my constant %reverse =";
    for %reverse.sort(*.key) {
        my $key := .key;
        my @values = .value<>;
        say @values.elems > 1
          ?? "  '$key', \$(<@values[]>),"
          !! "  '$key', @values.head.raku(),";
    }
    say ";";

    # we're done for this role
    say "#- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE";
    say $end;
}

# close the file properly
$*OUT.close;

# vim: expandtab sw=4


