#!/usr/bin/perl
#------------------------------------------------------------ 
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------ 
use strict;
#use warnings;

use File::Path;
use File::Find;
use Data::Dumper;
use Getopt::Std;
use Carp;

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

use lib '/app/tools/rps/lib';
use RPS::RoyaltyRun::Status;
use RPS::Statement::Artist::PDF;
use RPS::Statement::Mechanical::PDF;
use RPS::RoyaltyRun::Status;
use RPS::DB::Item::ArtistRoyaltyRun;
use RPS::DB::Item::MechanicalRun;
use RPS::DB::Item::ArtistRoyaltyStatement;
use RPS::DB::Item::MechanicalStatement;


# This determines how much output we spew forth to STDERR.
# The user can set this with the -V command-line argument.
#
my $gVerbosityLevel = 1;
# Parse the command-line, then create the PDF!
#
my %options;
parseCommandLine(\%options);
my @clientIDs;
if ($options{clientID})
{
    push @clientIDs, $options{clientID};
}
else
{
    @clientIDs = _getLocalClientIDs();
}

foreach my $clientID (@clientIDs)
{
    my $appSingleton = Common::RSApp->new(clientID => $clientID);

    # Fix mechanical statements first
    #
    my $allMechRuns = RPS::DB::Item::MechanicalRun->GetAll();
    while (my $mechRun = $allMechRuns->next())
    {
        next unless (RPS::RoyaltyRun::Status::kComplete == $mechRun->status
         || RPS::RoyaltyRun::Status::kCommitted == $mechRun->status
         || RPS::RoyaltyRun::Status::kClosed == $mechRun->status);

        my $path = RPS::Statement::Mechanical::PDF::StatementPathFromRunID($mechRun->mechanical_run_id);
        if (! -d $path)
        {
            report("NO PATH FOR $path");
        }
        next unless -d $path;

        # Grab all the .pdf files in that directory, so we can tell whether we
        # have a file that we can't rename.
        #
        my %oldFiles;
        my %noMatch;
        opendir(DIR, $path) or die "can't opendir $path: $!";
        while (defined (my $file = readdir(DIR)))
        {
            if ($file =~ m/.+\.pdf$/)
            {
                $oldFiles{"$path$file"} = 1;
            }
        }

        my $allMechStatements = RPS::DB::Item::MechanicalStatement->GetByMechanicalRunID($mechRun->mechanical_run_id);
        while (my $mechStatement = $allMechStatements->next())
        {
            # If we already _have_ the 'good' name, yay!
            #
            my $newName = RPS::Statement::Mechanical::PDF::StatementFileNameFromDBItem($mechStatement);
            if (-f "$path$newName")
            {
                report("$path$newName exists, nothing to do");
                delete $oldFiles{"$path$newName"};
                next;
            }


            # Do we have the file using the 'pretty name'?
            # If so, we want to rename it to the new name.
            #
            my $prettyName = RPS::Statement::Mechanical::PDF::PrettyStatementFileNameFromDBItem($mechStatement);
            if (-f "$path$prettyName")
            {
                report("renaming $path$prettyName to $path$newName");
                delete $oldFiles{"$path$prettyName"};
                rename("$path$prettyName", "$path$newName");
                next;
            }


            # Perhaps this client is still using the real old-skool name?
            #
            my $pubIDToken = '_' . $mechStatement->publisher_id . '_';
            my $oldName = $prettyName;
            $oldName =~ s/$pubIDToken/_/;

            if (-f "$path$oldName")
            {
                report("renaming $path$oldName to $path$newName");
                delete $oldFiles{"$path$oldName"};
                rename("$path$oldName", "$path$newName");
                next;
            }

            # So... we can't seem to find this file.  Either it is missing, or
            # it matches one of the old files but the publisher name is now different.
            # We'll have to sort that out manually...
            #
            $noMatch{"$path$newName"} = 1;
        }

        # Let's see what we have left over.
        #
        if (scalar keys %oldFiles > 0)
        {
            report("The following files could NOT BE MATCHED to a new file name:");
            foreach my $filename (keys %oldFiles)
            {
                report("   $filename");
            }
        }

        if (scalar keys %noMatch > 0)
        {
            report("The following NEW files could NOT BE MATCHED to an old file name:");
            foreach my $filename (keys %noMatch)
            {
                report("   $filename");
            }
        }
    }

    # Fix artist statements 
    #
    my $allArtistRuns = RPS::DB::Item::ArtistRoyaltyRun->GetAll();
    while (my $artistRun = $allArtistRuns->next())
    {
        next unless (RPS::RoyaltyRun::Status::kComplete == $artistRun->status
         || RPS::RoyaltyRun::Status::kCommitted == $artistRun->status
         || RPS::RoyaltyRun::Status::kClosed == $artistRun->status);

        my $path = RPS::Statement::Artist::PDF::StatementPathFromRunID($artistRun->artist_royalty_run_id);
        if (! -d $path)
        {
            report("NO PATH FOR $path");
        }
        next unless -d $path;

        # Grab all the .pdf files in that directory, so we can tell whether we
        # have a file that we can't rename.
        #
        my %oldFiles;
        my %noMatch;
        opendir(DIR, $path) or die "can't opendir $path: $!";
        while (defined (my $file = readdir(DIR)))
        {
            if ($file =~ m/.+\.pdf$/)
            {
                $oldFiles{"$path$file"} = 1;
            }
        }

        my $allArtistStatements = RPS::DB::Item::ArtistRoyaltyStatement->GetByArtistRoyaltyRunID($artistRun->artist_royalty_run_id);
        while (my $artistStatement = $allArtistStatements->next())
        {
            # If we already _have_ the 'good' name, yay!
            #
            my $newName = RPS::Statement::Artist::PDF::StatementFileNameFromDBItem($artistStatement);
            if (-f "$path$newName")
            {
                report("$path$newName exists, nothing to do");
                delete $oldFiles{"$path$newName"};
                next;
            }


            # Do we have the file using the 'pretty name'?
            # If so, we want to rename it to the new name.
            #
            my $prettyName = RPS::Statement::Artist::PDF::PrettyStatementFileNameFromDBItem($artistStatement);
            if (-f "$path$prettyName")
            {
                report("renaming $path$prettyName to $path$newName");
                delete $oldFiles{"$path$prettyName"};
                rename("$path$prettyName", "$path$newName");
                next;
            }


            # Perhaps this client is still using the real old-skool name?
            #
            my $pubIDToken = '_' . $artistStatement->payee_id . '_';
            my $oldName = $prettyName;
            $oldName =~ s/$pubIDToken/_/;

            if (-f "$path$oldName")
            {
                report("renaming $path$oldName to $path$newName");
                delete $oldFiles{"$path$oldName"};
                rename("$path$oldName", "$path$newName");
                next;
            }

            # So... we can't seem to find this file.  Either it is missing, or
            # it matches one of the old files but the publisher name is now different.
            # We'll have to sort that out manually...
            #
            $noMatch{"$path$newName"} = 1;
        }

        # Let's see what we have left over.
        #
        if (scalar keys %oldFiles > 0)
        {
            report("The following files could NOT BE MATCHED to a new file name:");
            foreach my $filename (keys %oldFiles)
            {
                report("   $filename");
            }
        }

        if (scalar keys %noMatch > 0)
        {
            report("The following NEW files could NOT BE MATCHED to an old file name:");
            foreach my $filename (keys %noMatch)
            {
                report("   $filename");
            }
        }
    }
}


#
# Boring script stuff below...
#

sub parseCommandLine
{
    my ($settings) = @_;

    my %opt;
    getopts('c:V:', \%opt);

    if (defined $opt{c})
    {
        $settings->{clientID} = $opt{c};
    }

    if (defined $opt{V})
    {
        $gVerbosityLevel = $opt{V};
    }
}


sub usage
{
    print STDERR "\nusage: $0 -c <client_id> -r <artist_royalty_run_id> -p <output path>\n";
    print STDERR "\n";
    print STDERR "Arguments:\n";
    print STDERR "\t-c <client_id>\t\t\tThe client_id of the client to process\n";
    print STDERR "\t-r <artist_royalty_run_id>\tThe id of the artist royalty run\n";
    print STDERR "\t-p <output path>\t\tThe path to where we'll be saving these files\n";
}


sub report
{
    my ($string, $verbosity) = @_;
    $verbosity = 1 unless defined $verbosity;

    if ($gVerbosityLevel >= $verbosity)
    {
        print $string . "\n";
    }
}


sub _getLocalClientIDs
{
    # We have a nifty little script that will give us a list of client databases.
    #
    my $clientListString = `/app/tools/rps/bin/db/list_client_dbs.pl`;
    chomp $clientListString;


    # Find the client id that matches each database.
    #
    my @ids;
    my @dbNames = split(/ /, $clientListString);
    foreach my $dbName (@dbNames)
    {
        my $id = Common::RSDB::DBNameToClientID($dbName);
        push @ids, $id;

    }

    return @ids;
}


