#!/usr/bin/perl
# Script to manually gather the specified user's current and historical
# statement information.  It allows you to check if a user can "see"
# statements from the command line instead of logging into the payee
# portal as that user.
#
# Usage:
#   perl ./get_statements.pl -u userID [-c clientID] [-d]
# where
#   -u userID specifies the payee portal user_id whose statements need to
#             be looked at.  A portal user may receive statements for one
#             or more artist payees.  By default this script will return
#             all of the current and historical statements that the user
#             can access via the portal API.
#
#   -c clientID specifies the clientID to be used in limiting which artist
#             payees can be retrieved.  If omitted, all artist payee
#             statements from all clients will be returned.
#
#   -d is used to enable 'debug' data (e.g., use Dumper to display the
#   contents of the data hashes that would normally be JSON-ified and returned
#   via the API).  If omitted, we'll display a quick summary of the current and
#   historical statements.
#

use strict;
use warnings;

use Data::Dumper;
use Getopt::Std;

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

my %opt;
getopts('c:u:d', \%opt);
my $clientID     = $opt{c};
my $userID       = $opt{u};
my $gShowDetails = $opt{d};


# Note: the GetCurrentStatementInfo and GetHistoricalStatements packages
# will both make client-specific connections for RSApp.  We'll create an
# initial connection to RSCOMMON to get things started.
#
my $appSingleton = Common::RSApp->new( clientID => 0 );


# The following is a little unconventional; what we're doing here is
# creating API command objects from a test script vs. through the
# Apache command handler.  In order to do that, we need to redefine some
# inherited methods which control things like session control and CGI
# parameter handling (both of which aren't applicable for our command-line
# script).  We also override createResponse since we're not concerned with
# returning HTTP responses and are only interested in looking at what
# would be in those responses.

undef *{API::Command::execute};
undef *{API::Command::getRouteParam};
undef *{API::Command::getParam};
undef *{API::Command::createResponse};

# This effectively bypasses authentication checking for the command...
*{API::Command::execute} = sub { return undef; };

# Redefine this to look locally instead of CGI
*{API::Command::getRouteParam} = sub {
    my $self = shift;
    my $p = shift;
    return $self->{$p};
};

# Redefine this to look locally instead of CGI
*{API::Command::getParam} = sub {
    my $self = shift;
    my $p = shift;
    return $self->{$p};
};


# Redefine this so we can dump out data vs. generating
# an Apache response
*{API::Command::createResponse} = sub {
    my ( $self, %args ) = @_;
    my $status = $args{status};
    my $data   = $args{data};
    my $msg    = $data->{msg} || '';

    if( $status == 200 ) {
        $self->_showData( \%{$args{data}} );
    } else {
        print "#createResponse: HTTP status($status) msg($msg)\n";
    }
};

# _showData is something we're adding to the Command base class
# so that we can see what the response would normally return
# via the API call.  The current and historical hashes are very
# similar, with the exception of the hash keys for the statement
# data ('currentStatement' vs 'historical_statement').
#
*{API::Command::_showData} = sub {
    my $self     = shift;
    my $hClients = \%{shift()};

    if ( $gShowDetails ) {
        print  Dumper($hClients) . "\n";
        return;
    }

    my $clients = $hClients->{clients};
    foreach my $clientData (@$clients) {
        MyCommon::printClient( \%$clientData );

        my @stmtData;
        if( exists $clientData->{historical_statement} ) {
            @stmtData = @{$clientData->{historical_statement}};
            print "  >>>> Historical Statements\n";
        } else {
            @stmtData = @{$clientData->{currentStatement}};
            print "  >>>> Current Statements\n";
        }

        if ( @stmtData == 0 ) {
            print "   No statements found!!!\n";
        } else {
            foreach my $stmt (@stmtData) {
                MyCommon::printStatement( \%$stmt );
            }
        }
    }
};

# Convenience method for printing client data
*{MyCommon::printClient} = sub {
    my $clientData = \%{shift()};
    my $email      = $clientData->{email};
    my $clientID   = $clientData->{client_id};
    my $clientName = $clientData->{client_name};
    print " client($clientName-$clientID) email($email)\n";
};

# Convenience method for printing statement data
*{MyCommon::printStatement} = sub {
    my $stmt = \%{shift()};

    my $stmtID    = $stmt->{statement_id};
    my $payorID   = $stmt->{payor_id};
    my $payorName = $stmt->{payor_name};
    my $runID     = $stmt->{run_id};
    my $runStatus = $stmt->{run_status};
    my $rStatusStr = RPS::RoyaltyRun::Status::StatusString($runStatus);
    my $prevBal   = $stmt->{previous_balance};
    my $total     = $stmt->{total};
    my $payable   = $stmt->{amount_payable};
    my $payeeName = $stmt->{payee_name};
    my $payeeID   = $stmt->{payee_id};

    print "   payee($payeeName-$payeeID) stmt($stmtID) payor($payorName-$payorID) "
        . "run($runID-$rStatusStr) prevBal($prevBal) "
        . "total($total) amtPayable($payable)\n";
};



my $deco = "user($userID)";
$deco .= " client($clientID)" if($clientID);

print "#### Getting Current Statement Information for $deco\n";
my $testCurrentStatements = MyGetCurrentStatements->new(
    ':clientId' => $clientID, ':runTypeId' => 'artist', 'userID' => $userID
);
$testCurrentStatements->execute();


print "\n";
print "#### Getting Historical Statement Information for $deco\n";
my $testHistoricalStatements = MyGetHistoricalStatements->new(
    ':clientId' => $clientID, ':runTypeId' => 'artist', 'userID' => $userID
);
$testHistoricalStatements->execute();


### Below are test-versions of API::Command::GetCurrentStatementInfo and
### API::Command::GetHistoricalStatements.  For both packages, we use the existing
### code under API::Command as much as possible.


{
    package MyGetCurrentStatements;
    use Data::Dumper;
    use lib '/app/tools/api/lib';
    use base 'API::Command::GetCurrentStatementInfo';

    sub new {
        my($class, %args) = @_;
        my $self = {};
        bless $self, $class;
        $self->init(%args);
    } # MyGetCurrentStatements::new

    sub init {
        my ( $self, %args) = @_;

        # These are the route params; we'll store them as globals...
        $self->{':clientId'}  = $args{':clientId'};
        $self->{':runTypeId'} = $args{':runTypeId'};

        # This is normally handled by API::Command::execute
        $self->{userID}       = $args{userID};

        return $self;
    } # MyGetCurrentStatements::init

    sub execute {
        my($self) = @_;
        #print "  calling SUPER->execute ...\n";
        $self->SUPER::execute();
    } # MyGetCurrentStatements::execute

    #
    # End of package MyGetCurrentStatements
    #
}




{
    package MyGetHistoricalStatements;
    use Data::Dumper;
    use lib '/app/tools/api/lib';
    use base 'API::Command::GetHistoricalStatements';

    our $ENV;

    sub new {
        my($class, %args) = @_;
        my $self = {};
        bless $self, $class;
        $self->init(%args);
    } # MyGetHistoricalStatements::new

    sub init {
        my ( $self, %args) = @_;

        $ENV{REQUEST_URI} = '';

        # These are the route params; we'll store them as globals...
        $self->{':clientId'}  = $args{':clientId'};
        $self->{':runTypeId'} = $args{':runTypeId'};

        # These are reqular params (optional); we'll store them as globals...
        $self->{'client'} = $args{'client'};
        $self->{'run'}    = $args{'run'};
        $self->{'payor'}  = $args{'payor'};
        $self->{'payee'}  = $args{'payee'};

        # This is normally handled by API::Command::execute
        $self->{userID}       = $args{userID};

        return $self;
    } # MyGetHistoricalStatements::init

    sub execute {
        my($self) = @_;
        $self->SUPER::execute();
    } # MyGetHistoricalStatements::execute

    #
    # End of package MyGetHistoricalStatements
    #
}

1;
