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

package RPS::ArtistRoyalty::Fast::Script::MapReserves;

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::Reserves;

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 Reserves");
    my $reserves = RPS::ArtistRoyalty::Fast::Static::Reserves->GetReserves( $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 reserves...");
    foreach my $reserveLine (@$reserves) {
        Log->info( "\n\nRESERVE LINE:", $reserveLine );

        my @reserveArray = split( "\t", $reserveLine );
        my $reserve = \@reserveArray;

        # 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, $reserve );
    }
}

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, $reserve ) = @_;

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

    # I'm not finding a purpose for the kRevenueBased column.
    #

    # !!! For debugging purposes, perhaps I can stuff the reserve_id into the sale_id slot?

    my $gFormatString = '%12d'                                                         # payee_id
      . "\t" . '%12d'                                                                  # album_id
      . "\t" . '%12d'                                                                  # artist_contract_id
      . "\t" . RPS::ArtistRoyalty::Fast::Mapped::Data::kTypeReserve . "\t" . '%12d'    # track_id
      . "\t" . '%12d'                                                                  # term_id
      . "\t" . '%1d'                                                                   # crossedflag
      . "\t" . '%12d'                                                                  # region_id  (seems a little redundant?)
      . "\t" . '%12d'                                                                  # income_source_id
      . "\t" . '%12d'                                                                  # channel_id
      . "\t" . '%12d'                                                                  # price_level_id
      . "\t" . '%20.08f'                                                               # rate
      . "\t" . '%20.08f'                                                               # price
      . "\t" . '%20.08f'                                                               # conversion_rate
      . "\t" . '%12d'                                                                  # sale_id
      . "\t" . '%12d'                                                                  # product_id
      . "\t" . '%12d'                                                                  # sales
      . "\t" . '%12d'                                                                  # returns
      . "\t" . '%20.08f'                                                               # revenue

      #     . "\t".'%12d'  # units reserved
      #     . "\t".'%18.06f'  # revenue reserved
      . "\t" . '%12d'       # units liquidated
      . "\t" . '%20.08f'    # revenue liquidated
      . "\t" . '%1d'        # is digital flag
      . "\t" . '%1d'        # distribution fee
      . "\t" . '%12d'       # prorate track count (FB113)
      . "\t" . '%20.08f'    # gross revenue
      . "\t" . '%d'         # periods remaining
      . "\n";

    # The old code did not necessarily trust the 'price' column.  If this is 0, it looked up
    # the price and used that.
    # I think we need to emulate that process here.
    #
    my $rate         = $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kEffectiveRate() ];
    my $priceLevelID = $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kPriceLevelID() ];
    my $price        = $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kPrice() ];

    # !!! We don't have the 'sale', obviously.  I think all the sale is used for is to get the incoming price level.
    # !!! Change this interface so it can be called from here.
    #    if (0 == $price)
    #    {
    #        ($priceLevel, $price, $rate) = $term->getRateData($sale, $productTerm, $productPrices, $incomeSourceID);
    #    }

    print $outFD sprintf(
        $gFormatString,
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kArtistPayeeID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kAlbumID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kArtistContractID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kTrackID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kArtistContractTermID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kCrossed() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kRegionID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kIncomeSourceID() ],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kChannelID() ],
        $priceLevelID,
        $rate,
        $price,
        1,
        $reserve->[RPS::ArtistRoyalty::Fast::Static::Reserves::kArtistContractTermReserveID],
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kProductID() ],
        0,
        0,
        0,
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kUnits() ],                # units liquidated
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kRevenue() ],              # revenue liquidated
        0,
        0,
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kProrateTrackCount() ],    # FB113
        0,
        $reserve->[ RPS::ArtistRoyalty::Fast::Static::Reserves::kPeriodsRemaining() ],
    );

}

1;
