#!/usr/bin/perl
use strict;

# -----------------------------------------
# input params:
#
# 	- client_id
# 	- file_id
#
# -----------------------------------------
# what it does:
#
# 	- get file record from db
# 	- if status is NEW or IN_QUEUE
# 		- change status to PROCESSING
# 		- set import_pid to this pid ($$)
# 		- import file
# 		- if success
# 			- change status to OPEN
#		- else
#			- fail?
#	- elsif status is PROCESSING
#		- if import_pid is not running
#			- try to re-import file
#		- else
#			- do nothing
#	- else
#		- do nothing
#
# -----------------------------------------

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

use lib '/app/tools/bookpub/lib';
use BookPub::Tracker::File;
use BookPub::Sale::File;
use BookPub::Price::Validator;
use BookPub::Sale::Report::Royalty::SalesFileValidator;

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

use FindBin;

import_sales_file();

sub import_sales_file {
    my $debug    = 0;
    my $continue = 0;

    # Match a leading argument of -d / --debug / -c / --continue
    while ( $ARGV[0] =~ m/^\-{1,2}([dc])/ ) {
        if    ( $1 eq 'd' ) { $debug    = 1; }
        elsif ( $1 eq 'c' ) { $continue = 1; }
        shift @ARGV;
    }

    my $client_id = $ARGV[0] or return usage("no client id passed");
    my $file_id   = $ARGV[1] or return usage("no file id passed");

    my $service_id = $ARGV[2];
    my $version    = $ARGV[3];
    my $file_path  = $ARGV[4];

    if ( $service_id || $version ) {
        return usage('both service_id AND version_num must be supplied, or neither at all') unless ( $service_id && $version );
    }

    # Instantiate the Application Singleton object.  This will initialize our global environment.
    #
    my $appSingleton = Common::RSApp->new( clientID => $client_id );

    $debug && Common::Log::LOGGER->setLogLevel('debug');

    my $file = BookPub::Tracker::File->new( fileID => $file_id );
    if ( !$file || $file->FileID != $file_id ) {
        return usage("File $file_id was not found.");
    }

    # - if status is NEW
    #
    if ( BookPub::DB::Item::File::STATUS_NEW() == $file->FileStatus || BookPub::DB::Item::File::STATUS_IN_QUEUE() ) {

        # - change status to PROCESSING
        # - set import_pid to this pid ($$)
        # !!! JPK - Do I want import_pid anymore?   Seems like we really want the 'job' id.
        #
        $file->FileStatus(BookPub::DB::Item::File::STATUS_PROCESSING);

        #		$file->ImportPID($$);
        $file->save();

        unless ( Common::Util::is_interactive() ) {
            Common::Log::Print("-running as: '$FindBin::Bin/$FindBin::Script @ARGV'");
        }

        # - parse sales file
        my $sf = BookPub::Sale::File->new( client_id => $client_id );
        my $success = $sf->ParseFull(
            client_id  => $client_id,
            file       => $file,
            service_id => $service_id,
            version    => $version,
            file_path  => $file_path,
        );
        my $error = $sf->errstr;
        Common::Log::Print("ParseFull returned '$success', error = '$error'");

        if ( $success && !length $error ) {

            # no_save so we only make one db hit, not two
            # !!! lame interface.  don't save ever unless you mean it...
            #
            #			$file->UpdateSummary(no_save => 1);
            $file->updateSummary();

            # Now we're going to make sure we have everything we need to include this in an output file.
            my $validForOutput = BookPub::Sale::Report::Royalty::SalesFileValidator::Validate($file_id);

            if ($validForOutput) {

                # Now do some price validation
                my $validator = new BookPub::Price::Validator( fileID => $file->FileID );
                $validator->run();

                # files with no records are just placeholders so they can be closed
                # also need to clear the md5sum so other empty files won't match
                if ( $file->Records() == 0 ) {
                    print STDERR "empty file\n";
                    $file->Revenue(0);
                    $file->Units(0);
                    $file->FileStatus(File::File::STATUS_OPEN);
                    $file->MD5Sum(undef);
                } else {
                    $file->FileStatus(File::File::STATUS_OPEN);
                    $file->MD5Sum( Common::Util::md5sum( $file->FileDir . '/' . $file->FileName . $file->Generation ) )
                      unless $file->MD5Sum;
                }

                if ( my $error = $sf->errstr ) {
                    $file->Notes($error);
                    Common::Log::Print("The file was imported with error(s): $error");
                }
                $file->DateProcessed( Common::Util::today_and_now() );
                $file->save();
            } else {

                # This file would cause an error if we tried to generate an output file with it,
                # so we're putting it on hold.
                $file->FileStatus(File::File::STATUS_ON_HOLD);
                $file->MD5Sum( Common::Util::md5sum( $file->FileDir . '/' . $file->FileName . $file->Generation ) ) unless $file->MD5Sum;
                $file->DateProcessed( Common::Util::today_and_now() );
                $file->save();
            }
        } else    # import failed or had errors
        {
            if ($error) {
                $file->Errors($error);
                Common::Log::Print("error during parsing: $error");
            }
            $file->FileStatus(File::File::STATUS_INVALID);
            $file->save();
        }
    }
}

sub usage {
    my $err = shift;

    print STDERR <<EofUSAGE;
ERROR: $err
Usage: import_sales_file.pl CLIENT_ID FILE_ID [SERVICE_ID VERSION_NUM ALT_FILE_PATH]
EofUSAGE

    return 1;
}
