#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2011 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------
package Report::Dynamic::Process::CleanupReports;

use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/report/lib';
use Report::DB::Item::Report;

use base 'Report::CronScript';

sub _options {
    {
        report_id => {
            short       => 'y',
            description => 'Report ID',
            parameter   => 'i',
        },
    };
}

sub _process {
    my $self = shift;

    $self->_removeExpiredReports();
    $self->_cleanupOrphanedFiles();
}

# Remove expired files.
sub _removeExpiredReports {
    my $self = shift;
    Log->info("-- Checking for expired reports");

    my $collection = Report::DB::Item::Report->GetAllNotDeleted();

    while ( my $reportItem = $collection->next() ) {
        my $report = $self->_reportFactory()->Fetch( $reportItem->report_id );

        # we won't get a report object from the factory for reports that
        # have been generated, but subsequently deprecated
        # (e.g. Catalog/Album* reports)
        if ( defined $report ) {
            $report->expireReport();
        }

    }
}

# Remove files without a database report record.
sub _cleanupOrphanedFiles {
    my $self = shift;
    Log->info("-- Removing orphanded files");

    my @dirs = $self->_reportFactory->GetReportDirs();

    foreach $baseDir (@dirs) {
        my $dir = $baseDir . '/' . Common::RSApp::GetClientID();
        if ( -d $dir ) {
            $self->_removeOrphans($dir);

        }
    }
}

sub _removeOrphans {
    my $self = shift;
    my $dir = shift || die;

    Log->info("  - Scanning $dir for orphans");

    opendir( DIR, $dir ) || die $!;

    while ( my $file = readdir(DIR) ) {
        next if ( $file =~ /^\./ );    # skip hidden files

        my $base = $file;
        $base =~ s/\.\w+$//;

        Log->debug("Filename: $file, Report ID: $base");

        my $report = $self->_reportFactory()->Fetch($base);
        Log->debug( "   - Report found with status: " . $report->status ) if ($report);

        # If the report doesn't exist or it is in a failed or canceled state
        # consider it orphaned.
        if (  !$report
            || $report->status eq Report::DB::Item::Report::kStatusCancelled
            || $report->status eq Report::DB::Item::Report::kStatusDeleted
            || $report->status eq Report::DB::Item::Report::kStatusError ) {
            Log->debug("   - unlink $dir/$file");

            # If this fails, we'll move on to the next file (and log the error).
            # We don't want to stop just because we ran into some file with weird permissions.
            #
            if ( !unlink("$dir/$file") ) {
                Log->error("unlink failed for '$dir/$file': $!");
            }
        }
    }

    close(DIR);
}

1;
