#!/usr/bin/perl
#
# Copyright (c) 2006 Zmanda Inc.  All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
#
# 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
# Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
# Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
#
#

use strict;
use warnings;
use File::Find;
use File::Basename;
use File::Spec::Functions;
use lib '/usr/local/lib/mysql-zrm';
use ZRM::Common;


#usage strings 
my $USAGE_PURGE_OPTIONS_STRING=
		"\t\t[--destination <directory name>]\n\tPlease note --backup-set is no longer necessary to be specified.\n\tIt has been kept for backward compatibility.";  

my @PURGEOPT=qw/destination=s/;

my @dirList;
my %destDirs;

#checks if file is ready to purge
#$_[0] is the name of index file
#Returns 1 if ready to purge else returns 0
sub checkIfReadyToPurge()
{
	my $index = $_[0];
	if( -f $index ){
		&parseIndexFile( $index );
		if( $indexdata{"retention-policy"} && 
		    $indexdata{"backup-date-epoch"} ){
			my $newtime = &getRetentionTimeInSecs( $indexdata{"retention-policy"} );
			my $tot = $indexdata{"backup-date-epoch"} + $newtime;
			if( $start_time gt $tot ){
				return 1;
			}
		}
	}
	return 0;
}

# find the directories to purge 
# $_[0] root directory from where to search
sub findListToPurge()
{
        find( {wanted => sub{}, postprocess => sub
                {
			my $x = catfile( $File::Find::dir, "index" );
			if( &checkIfReadyToPurge( $x ) ){
				push @dirList, $File::Find::dir;			
			}
			
                }}, $_[0]);
}

#Actually remove files and directories
#$_[0] directory to empty
sub findAndRemove()
{
        find( {wanted => sub{
			if( -f $_ ){
				my $r = unlink $_;
				if( $r eq 0 ){
					&printError( "could not delete $_ in directory $File::Find::dir\n" );
				}
			}
		}, postprocess => sub
                {
			my $r = rmdir( $File::Find::dir );	
			if( $r eq 0 ){
				&printError( "could not delete $File::Find::dir\n" );
			}
                }, no_chdir=>1}, $_[0]);
}

sub purgeDirs()
{
	foreach( keys%destDirs ){
		if( $verbose ){
			&printLog( "Searching directory $_ for Purging\n" );
		}
		purgeOneDir( $_ );
	}

}

#removes directories contained in @dirList 
# $_[0] destination dir to look
sub purgeOneDir()
{
	&findListToPurge( $_[0] );
	foreach( @dirList ){
		&printLog( "Purging Backup $_\n" );
		#&findAndRemove( $_ );
		&removeBackupDirectory( $_ );
	}
	@dirList = ();
}

# $_[0] backup directory
# $_[1] file containing mount details
sub removeSnapshots()
{
	&parseIndexFile( $_[1] );
	my $bset = $indexdata{"backup-set"};
	my $remcmd = "/usr/local/bin/mysql-zrm-manage-backup --remove-backup --dont-remove-index --backup-set $bset --source-directory $_[0] > $LOGGER 2>&1";
	my $r = system( $remcmd );
	if( $r > 0  ){
        	&printCommandOutputToLog( "ERROR", "remove-snapshot", $LOGGER );
               	&printError( "Remove snapshot failed. Command used is ".$remcmd."\n" );
        }
}

# $_[0] backup directory to remove
sub removeBackupDirectory()
{
	my $file = $_[0]."/".$ZRM_MOUNT_DETAILS;
	my $r = 1;
	if( -e $file ){
		$r = &removeSnapshots( $_[0], $file );
	}
	if( $r == 1 ){
		&findAndRemove( $_[0] );
	}
}

sub getPurgeDestinations()
{
	my @filelist1 = </etc/mysql-zrm/*/last_backup>;
	foreach( @filelist1 ){
		unless (open(TMPCONF, $_)) {
                	if( $verbose ){
                        	&printWarning( "Could not open file $_. $!\n" );
                	}
                	return;
        	}
        	my @tmparr = <TMPCONF>;
        	close(TMPCONF);
        	chomp (@tmparr);
		my $dir = dirname( $tmparr[0] );
		$destDirs{$dir} = $dir;
	}
}

#Does the purge action
sub doPurge()
{
	if( !$opt{"destination"} ) {
		&getPurgeDestinations();
	} else {
		if( !-d $opt{"destination"} ) {
			&printAndDie( "Cannot find destination ".$opt{"destination"}."\n" );
		}
		$destDirs{$opt{"destination"}} = 1;
	}
	&purgeDirs( );
	
}

#Sets up defaults 
sub setupDefaults()
{
        $action = "purge";
        $USAGE_STRING = $USAGE_COMMON_OPTIONS_STRING.$USAGE_PURGE_OPTIONS_STRING;
}

sub main()
{
        &setupDefaults();
        &initCommon(@PURGEOPT);
	&createConfigFile();
        &doPurge();
        &my_exit();
}

&main();

