#!/usr/bin/env perl
use strict;
use warnings;
use 5.014;

use Getopt::Long qw(:config gnu_getopt);
use App::Multigit;
use Future;
use curry;

my ($workdir, $repos_only);
GetOptions(
    'help|h' => sub {
        say usage();
        exit 0;
    },
    'workdir=s' => \$workdir,
    'repos-only' => \$repos_only
);

chdir $workdir;

my $future = App::Multigit::each(sub {
    my $repo = shift;

    $repo->run([ qw(git log --all --pretty=oneline) ])
        ->then(sub { show_results($repo, @_) })
        ->then(App::Multigit::report($repo));
});

my %done = $future->get;

for my $dir (keys %done) {
    chomp $done{$dir};
    if ($done{$dir}) {
        say for "$dir:", $done{$dir};
    }
    else {
        say $dir;
    }
}

sub show_results {
    my ($repo, $stdout, $stderr) = @_;
    my $dir = $repo->config->{dir};

    chomp $stdout;

    my @commits = parse_log($stdout);

    if (! @commits) {
        return Future->done;
    }

    if ($repos_only) {
        return Future->done(undef);
    }
    else {
        local $" = "\n";
        return Future->done(
            "@commits"
        );
    }
}

sub parse_log {
    my $log = shift;
    my $bz_re = qr/\b(bugzilla|bug|bz)\s*\Q$ARGV[0]/i;
    my $tracker_re = qr/\btracker\s*\Q$ARGV[0]/i;

    my @commits = map { /([[:xdigit:]]+)/ } grep { /$bz_re/ or /$tracker_re/ } split /\n/, $log;
}

sub usage {
<<'EOU';
Usage:
    mg closes [--repos-only] ID

    Searches the repositories for commits that mention ID.

    Commits are recognised as either bugs or trackers with the given ID by
    checking their commit messages for certain strings:
        BZ $id
        Bug $id
        Bugzilla $id

        Tracker $id

    For each repository with matching commits, the commit hashes are listed.

    Repositories with no matching commits are not reported at all.
EOU
}
