#!/usr/bin/perl -w

=head1 NAME

octo_logrotate - Octopussy Logrotate program

=head1 DESCRIPTION

octo_logrotate deletes log files older than the number of days defined in Device configuration

=cut

use strict;
use warnings;
use Readonly;

use Date::Manip;
use Getopt::Long;

use AAT::Syslog;
use AAT::Utils qw( ARRAY NULL );
use Octopussy;
use Octopussy::Device;
use Octopussy::Storage;

Readonly my $PROG_NAME => 'octo_logrotate';

my $quiet;

=head1 FUNCTIONS

=head2 Get_Directories($dir)

Returns list of Directories from Directory $dir

=cut

sub Get_Directories
{
    my $dir = shift;

    if ((-d $dir) && (opendir DIR, $dir))
	{
    	my @dirs = grep { !/^Incoming$/} grep { !/^Unknown$/ } grep { !/^\./ } readdir DIR;
    	closedir DIR;

    	return (@dirs);
	}

	return ();
}

=head2 Get_Logrotate_Limit($service, $type, $conf)

Gets logrotate & limit values for Service $service

=cut

sub Get_Logrotate_Limit
{
    my ($service, $type, $conf) = @_;

    my $logrotate = $conf->{logrotate};
    if (($type ne 'incoming') && ($type ne 'unknown'))
    {
        foreach my $ds (ARRAY($conf->{service}))
        {
            my $sid = $ds->{sid};
            $sid =~ s/ /_/g;
            if ((defined $ds->{logrotate}) && ($sid =~ /^$service$/))
            {
                $logrotate = $ds->{logrotate};
            }
        }
    }
    my $limit = Date::Manip::DateCalc('today', "-$logrotate days");
    $limit =~ s/^(\d{8}).+$/$1/;

    return ($logrotate, $limit);
}

=head2 Rotate_Logs($device)

Deletes Log Files for specified Device $device

=cut

sub Rotate_Logs
{
    my $device = shift;
    my $conf   = Octopussy::Device::Configuration($device);

    return () if (NULL($conf->{logrotate}));

    my $storage = Octopussy::Storage::Default();
    foreach my $t ('incoming', 'unknown', 'known')
    {
        my $dir =
            Octopussy::Storage::Directory($conf->{"storage_$t"}
                || $storage->{$t});
        my @services = (
            $t eq 'incoming' ? ('Incoming')
            : (
                $t eq 'unknown' ? ('Unknown')
                : Get_Directories("$dir/$device/")
              )
        );
        foreach my $s (@services)
        {
            my ($logrotate, $limit) = Get_Logrotate_Limit($s, $t, $conf);
            AAT::Syslog::Message($PROG_NAME, 'DELETE_LOGS_OLDER_THAN', $device,
                $s, $logrotate);
            print "Removing $device $s [$logrotate] logs files...\n"
                if (! $quiet);
            foreach my $y (Get_Directories("$dir/$device/$s"))
            {
                foreach my $m (Get_Directories("$dir/$device/$s/$y"))
                {
                    foreach my $d (Get_Directories("$dir/$device/$s/$y/$m"))
                    {
                        if (($y * 10_000 + $m * 100 + $d) < $limit)
                        {
                            system qq{rm -rf "$dir/$device/$s/$y/$m/$d/"};
                            AAT::Syslog::Message($PROG_NAME, 'DELETE_LOGS_DIR',
                                "$dir/$device/$s/$y/$m/$d/");
                        }
						else
						{	# Removes day directory if empty
							system 
							qq{rmdir "$dir/$device/$s/$y/$m/$d" 2> /dev/null};
                     		AAT::Syslog::Message($PROG_NAME, 
							'DELETE_EMPTY_LOGS_DIR',
                         	"$dir/$device/$s/$y/$m/$d")
							if (!-d "$dir/$device/$s/$y/$m/$d/");
						}
                    }
                    # Removes month directory if empty
                    system qq{rmdir "$dir/$device/$s/$y/$m" 2> /dev/null};
					AAT::Syslog::Message($PROG_NAME, 'DELETE_EMPTY_LOGS_DIR',
						"$dir/$device/$s/$y/$m")
                   		if (!-d "$dir/$device/$s/$y/$m");
                }
                # Removes year directory if empty
                system qq{rmdir "$dir/$device/$s/$y" 2> /dev/null};
				AAT::Syslog::Message($PROG_NAME, 'DELETE_EMPTY_LOGS_DIR',
               		"$dir/$device/$s/$y/")
					if (!-d "$dir/$device/$s/$y/");
            }
        }
    }

    return ($conf->{logrotate});
}

#
# MAIN
#
exit if (!Octopussy::Valid_User($PROG_NAME));

my $status = GetOptions(
    'q|quiet'           => \$quiet,
    );
    
foreach my $d (Octopussy::Device::List())
{
    Rotate_Logs($d);
}
system('/usr/sbin/octo_world_stats' . ($quiet ? ' --quiet' : ''));

=head1 AUTHOR

Sebastien Thebert <octo.devel@gmail.com>

=head1 SEE ALSO

octo_dispatcher, octo_extractor, octo_parser, octo_uparser, octo_scheduler

=cut
