#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::Statement::Mechanical::Text;

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::Util;
use Common::RSApp;
use Common::DB::Item::Client;

use lib '/app/tools/rps/lib';
use RPS::RoyaltyRun::Status;
use RPS::Mechanical::US::MechanicalRun;
use RPS::DB::Item::MechanicalRun;
use RPS::DB::Item::MechanicalStatement;
use RPS::DB::Item::Publisher;

sub _GetPublisherIDFromDBItem {
    my ( $class, $dbItem ) = @_;
    assert( 0, 'override this' );
}

sub _GetPayorIDFromDBItem {
    my ( $class, $dbItem ) = @_;
    assert( 0, 'override this' );
}

sub _BasePath {
    my ($class) = @_;
    assert( 0, 'override this' );
}

sub _GetStatementItem {
    my ( $class, $id ) = @_;
    assert( 0, 'override this' );
}

sub _GetRunItem {
    my ( $class, $id ) = @_;
    assert( 0, 'override this' );
}

sub _RunIDFromStatementItem {
    my ( $class, $statementDBItem ) = @_;
    assert( 0, 'override this' );
}

sub _GetFileLabel {
    my ( $class, $run );
    assert( 0, 'override this' );
}

sub _GetPublisher {
    my ( $class, $id ) = @_;
    assert( 0, 'override this' );
}

sub StatementFileNameFromID {
    my ( $class, $id ) = @_;
    assert($id);

    my $statement = $class->_GetStatementItem($id);
    return $class->StatementFilePathFromDBItem($statement);
}

sub StatementFileNameFromDBItem {
    my ( $class, $statementDBItem ) = @_;
    assert($statementDBItem);

    my $publisherID = $class->_GetPublisherIDFromDBItem($statementDBItem);

    my $fileName = "$publisherID.txt";

    return $fileName;
}

sub PrettyStatementFileNameFromID {
    my ( $class, $id ) = @_;
    assert($id);

    my $statement = $class->_GetStatementItem($id);
    return PrettyStatementFilePathFromDBItem($statement);
}

sub PrettyStatementFileNameFromDBItem {
    my ( $class, $statementDBItem ) = @_;
    assert($statementDBItem);

    my $runID         = $class->_RunIDFromStatementItem($statementDBItem);
    my $cleanRunLabel = $class->_RunLabelClean($runID);

    my $publisherID        = $class->_GetPublisherIDFromDBItem($statementDBItem);
    my $publisherNameClean = $class->_PublisherNameClean($publisherID);

    # If the state of the run is not 'COMMITTED' or 'CLOSED', then we want to add
    # "DRAFT" into the filename.
    #
    my $draft = '';
    my $run = $class->_GetRunItem($runID);
    if (   RPS::RoyaltyRun::Status::kCommitted != $run->status
        && RPS::RoyaltyRun::Status::kClosed != $run->status ) {
        $draft = "_DRAFT";
    }

    # RSD-8549
    if ( $class =~ /^RPS::Statement::Mechanical::(?:US|CA)::Text$/ ) {
        my $payorID = $class->_GetPayorIDFromDBItem($statementDBItem);

        return sprintf("%s_%s_%s_%s%s.txt",
            $publisherNameClean, $publisherID, $payorID, $cleanRunLabel, $draft
        );
    }

    my $fileName = sprintf("%s_%s%s.txt", $publisherNameClean, $cleanRunLabel, $draft);

    return $fileName;
}

# This returns the directory in which statement files can be found.
# client_id is optional - if ommitted, we'll use the current client id.
#
sub StatementPathFromRunID {
    my ( $class, $runID, $clientID ) = @_;
    assert($runID);

    $clientID = Common::RSApp::GetClientID() unless $clientID;
    my $clientData = Common::DB::Item::Client->Lookup( client_id => $clientID );
    my $clientName = $clientData->client_name_clean;

    return $class->_BasePath() . "/$clientName/$runID/";
}

# Going to create a little ram cache, since this code will often get called in a loop.
#
my %gRunLabel;

sub _RunLabelClean {
    my ( $class, $runID ) = @_;

    if ( !defined $gRunLabel{$class}{$runID} ) {
        my $run = $class->_GetRunItem($runID);
        assert( $run, "ERROR - runID $runID is invalid" );

        my $fileLabel = $class->_GetFileLabel($run);
        $gRunLabel{$class}{$runID} = Common::Util::clean_name($fileLabel);
    }

    return $gRunLabel{$class}{$runID};
}

my %gPublisherName;

sub _PublisherNameClean {
    my ( $class, $publisherID ) = @_;

    if ( !defined $gPublisherName{$class}{$publisherID} ) {
        my $publisher = $class->_GetPublisher($publisherID);
        assert( $publisher, "ERROR - publisher id $publisherID is invalid" );

        my $publisherName = $publisher->publisher_name;

        # Replace '&' with 'and' - the normal clean function doesn't do that.
        #
        $publisherName =~ s/ \& / and /g;
        $gPublisherName{$class}{$publisherID} = Common::Util::clean_name($publisherName);
    }

    return $gPublisherName{$class}{$publisherID};
}

1;
