#!/usr/bin/perl -w
#
# Copyright (c) 2007 Miek Gieben
# See LICENSE for the license
# clear out the backup directory

use strict;

use Getopt::Long qw(:config no_ignore_case bundling);
use File::Basename;
use File::Path;
use Date::Parse;

# common functions
my $prefix="/usr";
require "${prefix}/share/rdup/shared.pl" or die "** Require \`shared.pl' failed";

my $progName = basename $0;
my ($help, $dry, $version, $verbose, $log, $simple, $purgeDir);

GetOptions("h" => \$help,
        "V" => \$version,
        "n" => \$dry); 	  

usage() if $help;
version($progName) if $version;

die "** Need a directory to purge in" if $#ARGV < 0;
$purgeDir = $ARGV[0];

my $hostname = `hostname`; chomp $hostname;

if (exist($purgeDir) == 0) {
        die "** `$purgeDir' does not exist " unless -d _;
}

my $cepoch = time();
# read the top-level backup directory
my(@myear);
opendir(DIR, $purgeDir) || die "** Can't opendir $purgeDir: $!";
@myear = grep { !/^\./} readdir(DIR);
closedir DIR;

# for each dir, see what's inside and decide what to delete
my(@days);
foreach(@myear) {
	my $m = $_;
	opendir(DIR, "$purgeDir/$m") || next;
	@days = grep { !/^\./} readdir(DIR);
	closedir DIR;
		
	my $year = substr $m, 0, 4;
	my $mon  = substr $m, 4, 2;

	if ($year !~ /^-?\d/ || $mon !~ /^-?\d/) {
		next;
	}

	if (int($year) <= 1900 || int($year) > 3000) {
		warn "** Not a valid year: $year";
		next;
	}

	if (int($mon) <= 0 || int($mon) > 12) {
		warn "** Not a valid month: $mon";
		next;
	}

	foreach(@days) {
		my $directory = "$purgeDir/$m/$_";
		if (retain(int($year), int($mon), int($_)) == 1) {
			warn "** Deleting $directory" if $dry;
			if (! $dry) {
				rmtree $directory or warn "** Cannot remove $directory";
			}
		} else {
			warn "** Keeping $directory" if $dry;
		}
	}
}


# last 30 days everything
# last 100 days everthing every 7 days
# last 1000 days everthing every 100 days

sub retain {
	my ($year, $mon, $day) = @_;
	my $epoch = str2time("$year-$mon-$day");
	my $sec = $cepoch - $epoch;

	# Within 30 days interval -> keep
	if ($sec < (30 * (3600 * 24))) {
		return 0;
	}
	# Within 100 days -> keep every 7'th
	if ($sec < (100 * (3600 * 24))) {
		if (($day - 1) % 7 == 0) {
			return 0
		}
	}
	# Within 1000 days -> keep every 100
	if ($sec < (1000 * (3600 * 24))) {
		if (($day - 1) % 100 == 0) {
			return 0
		}
	}
	return 1;
}

sub usage {
        print "$progName [OPTIONS] DIRECTORY\n\n";
        print "Logorithmic purge old backups from DIRECTORY\n\n";
        print "OPTIONS\n";
        print " -n      dry-run, print what is done, but don't commit it\n";
        print " -h      this help\n";
        print " -V      print version\n";
        exit 0;
}
