#!/bin/sh

# copyright, licensing and documentation at the end

set -e
set -u

usage() {
    perl -MPod::Usage=pod2usage -e"pod2usage(-input => '$0', -verbose=>99, -sections=>[qw(SYNOPSIS DESCRIPTION)])"
    exit 1
}

STATS=
VERBOSE=
HAVE_BC=

while getopts vsh opt; do
    case $opt in
        h) usage;;
        s) STATS=1
           if which bc > /dev/null 2>&1; then
               HAVE_BC=1
           else
               echo "W: 'bc' not available, stats will use byte units" >&2
           fi
        ;;
        v) VERBOSE=1;;
        ?) usage;;
    esac
done

shift `expr $OPTIND - 1`

[ -z "${1:-}" ] || usage

cd "${DPT_PACKAGES:?}"

if [ -n "$HAVE_BC" ]; then
    calc() {
        ( echo "scale=1"; echo "$@" ) | bc
    }
else
    calc() {
        echo $(( "$@" ))
    }
fi

human() {
    local K_DIV=1024
    local M_DIV=$(( $K_DIV * $K_DIV ))
    local G_DIV=$(( $M_DIV * $K_DIV ))

    if [ -n "$HAVE_BC" ]; then
        if [ `calc  "$1 / $G_DIV >= 1.1"` = "1" ]; then
            echo `calc "$1 / $G_DIV"`G
        elif [ `calc "$1 / $M_DIV > 1.1"` = "1" ]; then
            echo `calc "$1 / $M_DIV"`M
        elif [ `calc "$1 / $K_DIV > 1.1"` = "1" ]; then
            echo `calc "$1 / $K_DIV"`K
        else
            echo $1
        fi
    else
        echo $1
    fi
}

TOTAL_BEFORE=0
TOTAL_AFTER=0
for d in `find . -maxdepth 1 -type d`; do
    [ -d "$d/.git" ] || continue

    if [ -n "$VERBOSE" ]; then
        echo -n "`basename $d`"
    fi
    if [ -n "$STATS" ]; then
        BEFORE=`du -sbP $d/.git | cut -f1`
        TOTAL_BEFORE=$(( $TOTAL_BEFORE + $BEFORE ))
    fi
    GIT_DIR="$d/.git" git gc --quiet
    if [ -n "$STATS" ]; then
        AFTER=`du -sbP $d/.git | cut -f1`
        TOTAL_AFTER=$(( $TOTAL_AFTER + $AFTER ))
    fi
    if [ -n "$VERBOSE" ]; then
        echo -n " done."
        if [ -n "$STATS" ]; then
            printf " %s -> %s (-%s, %0.1f%%)"  \
                `human $BEFORE` `human $AFTER` \
                `human $(( $BEFORE - $AFTER ))` \
                `calc "100*($BEFORE-$AFTER)/$BEFORE"`
        fi
        echo
    fi
done

if [ -n "$STATS" ]; then
    GAIN=$(( $TOTAL_BEFORE - $TOTAL_AFTER ))
    printf "Total disk usage: %s -> %s (-%s, %0.1f%%)"  \
        `human $TOTAL_BEFORE` `human $TOTAL_AFTER` \
        `human $GAIN` \
        `calc "100*($GAIN)/$TOTAL_BEFORE"`
fi

exit 0

POD=<<'EOF'
=head1 NAME

dpt-gc - swipe pkg-perl working directories

=head1 SYNOPSIS

B<dpt gc> [I<option>...]

=head1 DESCRIPTION

B<dpt gc> runs L<git(1)> garbage collection in cloned pkg-perl's repositories. It is suitable to be run from L<cron(1)>, e.g. weekly.

=head1 CONFIGURATION

B<dpt gc> uses the C<DPT_PACKAGES> environment variable. If
C<DPT_PACKAGES> is not defined, the command fails.

See L<dpt-config(5)> for details.

=head1 OPTIONS

=over

=item B<-h>

Display usage information.

=item B<-s>

Display statistics about disk usage before and after garbage collection.

=item B<-v>

Verbose operation. Let L<git-gc(1)> emit progress messages.

=back

=head1 COPYRIGHT & LICENSE

Copyright 2013 Damyan Ivanov L<dmn@debian.org>

This program is free software, licensed under the same term as perl.

=cut
EOF
