#!/usr/bin/perl
# Script to show and/or set Orchard client configuration settings.
#
# To show settings for a specific Orchard-enabled client:
#    ./config_orchard.pl -c 202 --list
#
# To show settings for all clients:
#    ./config_orchard.pl --list
#
# To set the user_id for Orchard notifications:
#
#    ./config_orchard.pl -c 202 -u 316
#
# To configure a client to scan for quarterly reports:
#
#    ./config_orchard.pl -c 202 --quarterly
#    Note: client's Orchard account MUST be configured the same
#    way in OWS or you will not be able to retrieve any reports.
#
# To configure a client to not scan for any reports:
#
#    ./config_orchard.pl -c 202 -s 0
#
# To enable report generation requests for any missing reports:
#
#    ./config_orchard.pl -c 202 -s 2
#    Note: any report requests will appear in OWS.  Make sure the
#    Orchard client is aware of this before enabling this option.
#
# To check for existing reports only (no report generation requests
# will be submitted with this option, so the reports must be
# generated in OWS):
#
#    ./config_orchard.pl -c 202 -s 1
#
# To set the starting scan period for a client:
#
#    ./config_orchard.pl -c 202 -p 200
#    (sets the starting period as August 2015)
#
# Run with "-h" option for additional info.
#
use strict;
use Data::Dumper;

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::RSApp;
use Common::DB::Item::OrchardClient;
use Common::OrchardFetcher::OrchardPeriod;

use Getopt::Long;
use File::Basename;

my %args;
parseCommandLine(\%args);
my $clientID = $args{client_id};
my $userID = $args{user_id};
my $showSettings = $args{list};

# Scan option.  Configures an Orchard client and how it will interact
# with the Orchard accounting statement API.
#
# 0 = no scan
# 1 = check and download report only if they already exist
# 2 = scan and submit report generation request if no report found (this
#     last option will show up on the client's OWS; use only with the client's
#     permission).
#
my $scanOption = $args{scan_mode};
my $schedule = $args{schedule};
my $startPeriod = $args{start_period};


my $appSingleton = ($clientID) ? Common::RSApp->new(clientID => $clientID) :
                                 Common::RSApp->new(clientID => 0);

my $cdbo = Common::RSApp::GetCommonDB();
my $dbh = $cdbo->DBH;

my $o;
if( $clientID )
{
    $o = Common::DB::Item::OrchardClient->Lookup(client_id=>$clientID);
    die("$clientID NOT A VALID ORCHARD CLIENT !!!") if(!$o);
}

my %gPeriodInfo = Common::OrchardFetcher::OrchardPeriod::getPeriodHash();

if( $showSettings )
{
    my @clients;
    if( $clientID )
    {
        push @clients, $o;
    }
    else
    {
        my $c = Common::DB::Item::OrchardClient->GetAll();
        while( $c->hasNext() )
        {
            push @clients, $c->next();
        }
    }

    foreach my $o (@clients)
    {
        my $email = getUserEmail($o->user_id);

        my $name = getClientName($o->client_id);

        print "##### Configuration for RPS client_id ". $o->client_id .
            " '". getClientName($o->client_id) . "' " .
            " (Orchard account ". $o->account_id  .")\n";

        print "  Orchard notifications will be sent to user_id " . ($o->user_id || 0) . " (". $email .")\n";

        my $scanType = ($o->status == 0) ? 'No scan' :
                       ($o->status == 1) ? 'Read only' :
                       ($o->status == 2) ? 'Generate as needed' : 'UNKNOWN';
        print "  Scan option is set to ". $o->status . " ($scanType)\n";

        my $schedType = ($o->scan_schedule == 1) ? 'Monthly' :
                        ($o->scan_schedule == 2) ? 'Quarterly' : 'UNKNOWN';

        print "  Scan schedule is set to ". $o->scan_schedule . " ($schedType)\n";

        my $startPeriod = $o->start_period;
        my $p = _getPeriod( $startPeriod );
        print "  Scans will start at period $startPeriod (". $p->{start_date} .")\n";

        print "\n";
    }

    exit;
}

unless ($clientID) { usage("ClientID required to change settings"); };

if($userID)
{
    my $email = getUserEmail($userID);
    $o->user_id($userID);
    $o->save();
    print "Client $clientID has been updated to send Orchard notifications to user_id $userID ($email)\n";
}

if(defined $scanOption)
{
    if($scanOption =~ /^(0|1|2)$/)
    {
        my $old = $o->status;
        $o->status($scanOption);
        $o->save();
        print "Client $clientID scan status changed from $old to $scanOption\n";
    }
    else
    {
        print "Invalid scan option; valid values are 0 (no scan), 1 (read only) or 2 (generate if not found)\n";
    }
}

if($schedule)
{
    my $old = $o->scan_schedule;
    $o->scan_schedule($schedule);
    $o->save();
    print "Client $clientID scan schedule changed from $old to $schedule\n";
}

if($startPeriod)
{
    my $old = $o->start_period;
    $o->start_period($startPeriod);
    $o->save();
    print "Client $clientID start period changed from $old to $startPeriod\n";
}

### Subroutines below

sub getUserEmail {
    my $userID = shift;
    my $sql = "SELECT email FROM user WHERE user_id=$userID";
    my $sth = $cdbo->DoCmd($sql);
    my($email) = $sth->fetchrow_array();
    return $email || 'INVALID_USERID';
}


sub getClientName {
    my $clientID = shift;
    my $sql = "SELECT client_name FROM client WHERE client_id=$clientID";
    my $sth = $cdbo->DoCmd($sql);
    my($name) = $sth->fetchrow_array();
    return $name || 'NAME_NOT_FOUND';
}

sub parseCommandLine
{
    my ($a) = @_;
    my $userID;
    my $clientID;
    my $list;
    my $monthly;
    my $quarterly;
    my $scan;
    my $schedule;
    my $startPeriod;
    my $help;

    die if(!GetOptions(
        'c|client=i'   => \$clientID,
        'u|user=i'     => \$userID,
        's|scan=i'     => \$scan,
        'p|period=s'   => \$startPeriod,
        'l|list'       => \$list,
        'm|monthly'    => \$monthly,
        'q|quarterly'  => \$quarterly,
        'h|help'       => \$help,
    ));

    if( $monthly && $quarterly )
    {
        usage("Specify monthly or quarterly");
    }

    if( $scan && $scan !~ /^(0|1|2)$/ )
    {
        usage("Scan schedule must be 0 (ignore), 1 (read-only) or 2 (generate as needed)");
    }

    printHelp() if( $help );

    $schedule = ($quarterly) ? Common::OrchardFetcher::OrchardPeriod::kScanQuarterly :
                ($monthly)   ? Common::OrchardFetcher::OrchardPeriod::kScanMonthly : undef;

    $a->{client_id} = $clientID;
    $a->{user_id}   = $userID;
    $a->{list}      = $list;
    $a->{help}      = $help;
    $a->{schedule}  = $schedule;
    $a->{scan_mode} = $scan;
    $a->{start_period} = $startPeriod;
}

sub usage {
    my $err = shift;
    print "ERROR: $err\n\n";
    print "$0 -c clientID [-u userID] [--list] [--quarterly|--monthly] [--scan (0|1|2)] [--period NNNN]\n";
    printHelp();
}

sub printHelp {
    print "------------------------------------------------------------------------------------\n";
    print "This script configures the Orchard client settings for an Orchard-enabled RPS client.\n";
    print "Arguments:\n\n";
    print "-l|--list      Shows the current setting for a client and exits.  Info for all clients\n";
    print "               will be shown if client_id not specified.\n";
    print "\n";
    print "-c clientID    Specifies the RPS client to be configured.  This must be a valid client\n";
    print "               in the RSCOMMON.orchard_client table.\n";
    print "\n";
    print "-u userID      Specifies the RPS user_id to receive Orchard notifications.  This must be\n";
    print "               a valid user_id in the RSCOMMON.user table.\n";
    print "\n";
    print "-s scanMode    Specifies how the Orchard sales fetcher will scan for sales reports:\n";
    print "               0 = do not scan for any reports; effectively halts any new file ingestion\n";
    print "               1 = scan for and download/ingest any existing reports\n";
    print "               2 = similar to 1, but submit report generation requests for missing reports\n";
    print "\n";
    print "-p period      Set the starting period for scans.  This should be a single period representing\n";
    print "               the month to start scanning (see RSCOMMON.orchard_period).  For quarterly\n";      
    print "               clients, use the period for first month in the quarter.  E.g., use \"205\"\n";      
    print "               rather than \"205,206,207\" to start scanning for sales on or after 1/1/2016.\n";
    print "\n";
    print "-m|--monthly   Query the Orchard API using monthly period identifiers\n";
    print "-q|--quarterly Query the Orchard API using quarterly period identifiers\n";
    print "               The Orchard client must be configured in Workstation as either monthly or\n";
    print "               quarterly, and the setting used here MUST match workstation.  If you try\n";
    print "               to scan using monthly reporting periods and the client is setup as\n";
    print "               quarterly in workstation, then you will not get any sales data.\n";
    exit;
}

sub _getPeriod {
    my $period = shift;
    my $pinfo;
    foreach my $id (sort { $a <=> $b } keys %gPeriodInfo )
    {
        $pinfo = $gPeriodInfo{$id};
        my $pid   = $pinfo->{period};
        #my $pname = $pinfo->{period_name};
        #my $sdate = $pinfo->{start_date};
        #my $edate = $pinfo->{end_date};
        #print "[$id] period $pid name($pname) sdate($sdate) edate($edate)\n";
        return $pinfo if($pid eq $period);
    }
}

1;
