#!/usr/bin/perl

use strict;
use Getopt::Std;
use IO::File;
use Date::Calc;
use Data::Dumper;

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

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Expense;
use RPS::DB::Item::ExpenseType;
use RPS::DB::Item::ExpenseName;
use RPS::DB::Item::AlbumContract;
use RPS::DB::Item::TrackContract;
use RPS::DB::Item::AlbumContractAdvance;
use RPS::DB::Item::TrackContractAdvance;
use RPS::DB::Item::FinanceTransaction;

# Parse the command-line.
#
my ($clientID) = parseCommandLine();

$| = 1;

# Instantiate the application singleton object.
#
my $appSingleton = Common::RSApp->new( clientID => $clientID );

# create expense name
#
my $expenseNameObj = RPS::DB::Item::ExpenseName->Lookup( name => "Advance" );

if ( !$expenseNameObj ) {
    $expenseNameObj = RPS::DB::Item::ExpenseName->Create( name => "Advance" );
    $expenseNameObj->save();
}

# Commit any necessary updates.
#
convertAdvances();

sub convertAdvances {
    my %contractExpenseType = ();

    # do album advances first
    #
    my $albAdvColl = RPS::DB::Item::AlbumContractAdvance->GetAll();
    while ( $albAdvColl->hasNext() ) {
        my $albumContractAdvanceObj = $albAdvColl->next();

        my $albumContractObj = RPS::DB::Item::AlbumContract->Lookup( album_contract_id => $albumContractAdvanceObj->album_contract_id );
        next if ( !$albumContractObj );

        my $contractID = $albumContractObj->artist_contract_id;

        if ( !$contractExpenseType{$contractID} ) {

            # create an expense type for advance
            #
            my $newExpenseType = RPS::DB::Item::ExpenseType->Create(
                artist_contract_id => $contractID,
                expense_name_id    => $expenseNameObj->expense_name_id,
                percent            => 100,
            );
            $newExpenseType->save();
            $contractExpenseType{$contractID} = $newExpenseType->expense_type_id;
        }

        createExpenses(
            parentID      => $albumContractObj->album_contract_id,
            parentType    => RPS::DB::Item::Expense::kParentAlbumContract(),
            accountID     => $albumContractAdvanceObj->advance_account_id,
            expenseTypeID => $contractExpenseType{$contractID},
        );
    }

    # next do track advances
    #
    my $trkAdvColl = RPS::DB::Item::TrackContractAdvance->GetAll();
    while ( $trkAdvColl->hasNext() ) {
        my $trackContractAdvanceObj = $trkAdvColl->next();

        my $trackContractObj = RPS::DB::Item::TrackContract->Lookup( track_contract_id => $trackContractAdvanceObj->track_contract_id );
        next if ( !$trackContractObj );

        my $contractID = $trackContractObj->artist_contract_id;

        if ( !$contractExpenseType{$contractID} ) {

            # create an expense type for advance
            #
            my $newExpenseType = RPS::DB::Item::ExpenseType->Create(
                artist_contract_id => $contractID,
                expense_name_id    => $expenseNameObj->expense_name_id,
                percent            => 100,
            );
            $newExpenseType->save();
            $contractExpenseType{$contractID} = $newExpenseType->expense_type_id;
        }

        createExpenses(
            parentID      => $trackContractObj->track_contract_id,
            parentType    => RPS::DB::Item::Expense::kParentTrackContract(),
            accountID     => $trackContractAdvanceObj->advance_account_id,
            expenseTypeID => $contractExpenseType{$contractID},
        );
    }
}

sub createExpenses {
    my (%args) = @_;

    my $parentID      = $args{parentID};
    my $parentType    = $args{parentType};
    my $accountID     = $args{accountID};
    my $expenseTypeID = $args{expenseTypeID};

    my $transactionColl = RPS::DB::Item::FinanceTransaction->GetAccountTransactions( finance_account_id => $accountID );

    while ( $transactionColl->hasNext() ) {
        my $transactionObj = $transactionColl->next();

        my %params = (
            expense_type_id => $expenseTypeID,
            amount          => $transactionObj->amount,
            parent_type     => $parentType,
            parent_id       => $parentID,

            # usually this would be copied from the expense type, but we'll just hard code it here because we know it should always be 100
            percent => 100,
            memo    => $transactionObj->memo,
        );

        my $newExpense = RPS::DB::Item::Expense->Create(%params);
        $newExpense->save();
    }
}

sub parseCommandLine {
    my %opt;
    getopts( 'c:', \%opt );

    my $clientID = $opt{c};

    unless ( $clientID =~ /^\d+$/ && $clientID > 0 ) {
        die usage("You must specify a valid client ID");
    }

    return $clientID;
}

sub usage {
    my $errstr = shift;
    my $text = ($errstr) ? "ERROR: $errstr\n" : '';
    $text .= "Usage: $0 -c <clientID> -f <inputFile>\n";
    return $text;
}

