#!/usr/bin/perl -w
# Copyright (C) 2020-2021 Miquel Sabaté Solà <mikisabate@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# This script is a git plugin that allows you to list the top contributors of a
# certain repository (the current path by default, otherwise you have to
# indicate the path as an argument). This behavior can be tweaked with the
# following flags:
#
#   -n, --number
#       The number of authors to be displayed. Defaults to 10.
#   -s, --since
#       Display authors since "N months/years ago" (just like git's `--since'
#       flag). The whole history will be picked if this flag is not provided.
#
# Thus, the usage is as follows:
#
#   $ git who [-n | --number] [-s | --since] <path>
#
# This plugin is based on the work as seen on this .gitconfig file:
# https://gist.github.com/redguardtoo/d4ecd51f785bd117a6a0.

use strict;

##
# Config values.

# The number of authors to be shown.
my $number = 10;

# Fetch the git history from "N months/years ago" (just like git's `--since' flag).
my $since;

##
# Hic sunt dracones.

# Show the usage string and exit.
sub usage {
    my ($code) = @_;

    print "Usage: git who [-n | --number] [-m | --months] <path>\n";
    print "   -n, --number\tThe number of authors to be shown.\n";
    print "   -s, --since\tFetch the git history from \"N months/years ago\" (just like git's `--since' flag).\n";
    exit($code);
}

# Parsing options.
my %opts = ('n', $number, 's', $since, 'p', '');
my $found = 0;
for (my $it = 0; $it < @ARGV; $it++) {
    if ($ARGV[$it] eq '-n' || $ARGV[$it] eq '--number') {
        usage(1) if (!$ARGV[$it + 1]);
        $opts{n} = $ARGV[$it + 1];
        $it++;
    } elsif ($ARGV[$it] eq '-s' || $ARGV[$it] eq '--since') {
        usage(1) if (!$ARGV[$it + 1]);
        $opts{s} = $ARGV[$it + 1];
        $it++;
    } elsif ($ARGV[$it] eq '-h' && $ARGV[$it] eq '--help') {
        usage(0);
    } elsif ($ARGV[$it] =~ '^--?') {
        print "Unknown option `$ARGV[$it]'.\n\n";
        usage(1);
    } elsif ($found) {
        print "Already using `$opts{p}' as the path.\n\n";
        usage(1);
    } else {
        $opts{p} = $ARGV[$it];
        $found = 1;
    }
}

# Adding the different options into the end command.
my $cmd = "git log --format='%an'";
if ($opts{s}) {
    $cmd = $cmd . " --since='" . $opts{s} . "'";
}
if (length($opts{p}) > 0) {
    $cmd = $cmd . " " . $opts{p};
}

$cmd = $cmd . " | sort | uniq -c | sort -rn | head -n " . $opts{n};

# Let's rock!
exit(system($cmd) == 0);
