#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2012 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::ArtistRoyalty::Fast::Script::MapExpenses;

use strict;
use Data::Dumper;
use File::Path;

use lib '/app/tools/common/lib';
use lib '/app/tools/rps/lib';
use lib '/app/tools/raptor/lib';

use DB_File;

use Common::Util;
use Common::Log;
use Common::Parser;
use Common::WriteXML;

use RPS::ArtistRoyalty::Fast::Static::Expenses;
use RPS::ArtistRoyalty::Fast::Static::ProductTerms;
use RPS::ArtistRoyalty::Fast::Static::ProductPrices;
use RPS::ArtistRoyalty::Fast::Static::PaidSales;
use RPS::ArtistRoyalty::Fast::Static::IncomeSources;
use RPS::ArtistRoyalty::Fast::Static::RegionCountries;
use RPS::ArtistRoyalty::Fast::Static::Terms;

use RPS::ArtistRoyalty::Fast::Mapped::Data;

use RPS::ArtistRoyalty::Fast::TermType;

use base 'Common::Script';

sub _options {
    {
        client_id => {
            short       => 'c',
            required    => 1,
            description => 'Limit to this client id',
            parameter   => 'i'
        },
        data_path => {
            short       => 'd',
            required    => 1,
            description => 'path to directory containing static data',
            parameter   => 's'
        },
        output_path => {
            short       => 'o',
            required    => 1,
            description => 'path to directory to write output files',
            parameter   => 's'
        },
        #
        # For now we'll assume the sales data is in there as well.
        # Some day that may not be the case...

        index_range => {
            short       => 'i',
            required    => 0,
            description => 'First,Last data indexes to process.  Ex: -s0,10000',
            parameter   => 's',
        },
    };
}

sub _process {
    my ($self) = @_;

    my ( $firstIndex, $lastIndex ) = $self->_parseFirstLastIndex( $self->param('index_range') );

    my $dataPath = $self->param('data_path');

    my $outputDirectory = $self->param('output_path');

    # JPK - Should it be the responsibility of this process to create the directory if
    # it doesn't already exist?   It's a bit of a stretch, but then again it's convenient...
    #
    if ( !-d $outputDirectory ) {

        # !!! Might want to make this behavior optional...
        #
        mkpath($outputDirectory);
    }

    Log->info("Getting Expenses");
    my $expenses = RPS::ArtistRoyalty::Fast::Static::Expenses->GetExpenses( $dataPath, $firstIndex, $lastIndex );

    # This is the main output stream.
    # !!! We will possibly need more for error or missed sale logging...
    #
    my $incomeItemFD = $self->_openIncomeItemFileDescriptor($outputDirectory);

    Log->info("Processing expenses...");
    foreach my $expenseLine (@$expenses) {
        Log->info( "\n\nEXPENSE LINE:", $expenseLine );

        my @expenseArray = split( "\t", $expenseLine );
        my $expense = \@expenseArray;

        # Glean all the necessary identifiers out of the reserve record.
        # I don't think I should need to look at any other data...
        #
        # These are the records I need to map the reserve to the correct income item:
        #
        $self->_outputLine( $incomeItemFD, $expense );
    }
}

sub _openIncomeItemFileDescriptor {
    my ( $self, $outputDirectory ) = @_;

    open OUTPUT, "> $outputDirectory/" . RPS::ArtistRoyalty::Fast::Mapped::Data->FileName() . "_$$.unsorted" or die "ERROR: $!";

    return *OUTPUT;
}

sub _parseFirstLastIndex {
    my ( $self, $rangeString ) = @_;
    return unless $rangeString;

    my @bits = split( ',', $rangeString );
    if ( 2 != scalar @bits || ( $bits[1] <= $bits[0] ) ) {
        $self->usage('ERROR: sale_range is invalid.');
    }
    return ( $bits[0], $bits[1] );
}

sub _outputLine {
    my ( $self, $outFD, $expense ) = @_;

    Log->info( "outputLine: ", $expense );

    # Just to be consistent with the old code, we'll round off the rate to 4 places.
    #
    my $expenseRate = Common::RSMath::round( $expense->[RPS::ArtistRoyalty::Fast::Static::Expenses::kPercent], 4 );

    my $total = Common::RSMath::round( ( $expense->[RPS::ArtistRoyalty::Fast::Static::Expenses::kAmount] * ( $expenseRate / 100 ) ), 4 );

    # JPK - This padding is probably not necessary, since we're explicitly sorted with '-k' params.

    my $gFormatString = '%12d'                                                         # payee_id                         12
      . "\t" . '%12d'                                                                  # album_id              +13 = 25
      . "\t" . '%12d'                                                                  # artist_contract_id    +13 = 40
      . "\t" . RPS::ArtistRoyalty::Fast::Mapped::Data::kTypeExpense . "\t" . '%12d'    # track_id              +13 = 53
      . "\t" . '%12d'                                                                  # term_id               +13 = 66
      . "\t" . '%1d'                                                                   # crossedflag
      . "\t" . '%12d'                                                                  # expense_id            +13 = 79
      . "\t" . '"%s"'                                                                  # expense_name, quoted
      . "\t" . '"%s"'                                                                  # memo, quoted

      . "\t" . '%20.08f'                                                               # cost
      . "\t" . '%20.08f'                                                               # rate
      . "\t" . '%20.08f'                                                               # total
      . "\t" . '%20.08f'                                                               # default term rate
      . "\n";

    # I think we've got 283 chars per sale line, including the line feed.
    # S0, 283 - 79 = 203 spaces to pad plus 1 carriage return.

    print $outFD sprintf( $gFormatString,
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kArtistPayeeID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kAlbumID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kArtistContractID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kTrackID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kArtistContractTermID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kCrossed() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kExpenseID() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kName() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kMemo() ],
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kAmount() ],
        $expenseRate,
        $total,
        $expense->[ RPS::ArtistRoyalty::Fast::Static::Expenses::kDefaultTermRate() ],
    );

}

1;
