#!/usr/bin/perl
use strict;

use Data::Dumper;
use Getopt::Std;
use POSIX qw(ceil);
use POSIX ":sys_wait_h";
use Sys::Hostname;
use Carp;

use lib '/app/tools/common/lib';
use Common::DB::Item;
use Common::Assert;
use Common::TextProgressBar;
use Common::Timer;
use Common::DB::Item::Service;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::MechanicalCarryover;
use RPS::DB::Item::TrackLicense;
use RPS::DB::Item::Track;
use RPS::DB::Item::TrackContract;
use RPS::DB::Item::Master;
use RPS::DB::Item::Album;

#use RPS::DB::Item::License;
use RPS::DB::Item::LicenseReserve;
use RPS::DB::Item::LicenseReserveLiquidation;
use RPS::DB::Item::StatRate;
use RPS::DB::Item::ProductTrack;
use RPS::DB::Item::Song;

use RPS::DB::Item::Publisher;
use RPS::DB::Item::Product;
use RPS::DB::Item::ControlledComposition;

use RPS::DB::Item::AlbumContract;
use RPS::DB::Item::MechanicalRun;
use RPS::DB::Item::MechanicalStatement;
use RPS::DB::Item::MechanicalStatementItem;
use RPS::DB::Item::MechanicalStatementItem;
use RPS::DB::Item::MechanicalStatementTrack;
use RPS::DB::Item::MechanicalStatementLicense;
use RPS::DB::Item::MechanicalStatementAdjustmentItem;
use RPS::DB::Item::SaleMechanicalStatementItemMap;

use RPS::License::TrackLicense;
use RPS::License::TrackLicenseList;
use RPS::DB::Item::NewArtistContract;
use RPS::DB::Item::ReserveLiquidation;

# INTEGRATION
#
# We're getting rid of the seperate 'album_id' and 'track_id' fields.
# Instead, we'll have a single 'assert_id' - what that points to will
# be determined by 'product_type_id'.
#

my $gVerbosityLevel = 1;

# Parse the command-line options.
#
my %options;
_parseCommandLine( \%options );

my $upcAltMap = _getUPCAlt( $options{origClientID} );

_alterProduct( $options{clientID}, $upcAltMap );

sub _getUPCAlt {
    my ($clientID) = @_;

    # Instantiate the application singleton object.
    #
    my $appSingleton = Common::RSApp->new( clientID => $clientID );

    my $dbo = Common::RSApp::GetClientDB();
    my $sql = "SELECT album_id, upc_alt from album";
    my $sth = $dbo->DoCmd($sql);
    my %map;
    while ( my $hr = $sth->fetchrow_hashref() ) {
        $map{ $hr->{album_id} } = $hr->{upc_alt};
    }

    return \%map;
}

sub _alterProduct {
    my ( $clientID, $upcMap ) = @_;

    # Instantiate the application singleton object.
    #
    my $appSingleton = Common::RSApp->new( clientID => $clientID );
    _report("altering product table");

    # First, we'll add the new column.
    #
    _report("adding asset_id column");

    my $dbo = Common::RSApp::GetClientDB();
    my $sql = "ALTER TABLE product ADD COLUMN asset_id int(10) unsigned default NULL";
    if ( !$dbo->DoCmd($sql) ) {
        _report( "error " . $dbo->LastErrorStr() );
        return;
    }
    $sql = "ALTER TABLE product ADD COLUMN upc_alt varchar(25) default NULL";
    if ( !$dbo->DoCmd($sql) ) {
        _report( "error " . $dbo->LastErrorStr() );
        return;
    }

    # Now we'll move through the products, setting asset_id and upc_alt to the proper value.
    #
    $dbo = Common::RSApp::GetClientDB();
    $sql = "SELECT product_id, product_type_id, track_id, album_id from product";
    my $sth = $dbo->DoCmd($sql);
    while ( my $hr = $sth->fetchrow_hashref() ) {
        my $productID = $hr->{product_id};
        my $upcAlt;
        my $assetID;
        if ( 4 == $hr->{product_type_id} ) {
            $assetID = $hr->{track_id};
        } else {
            $assetID = $hr->{album_id};
            $upcAlt  = $upcMap->{$assetID};
        }

        $sql = "UPDATE product SET asset_id=$assetID, upc_alt=" . $dbo->DBQuote($upcAlt) . " WHERE product_id=$productID";
        $dbo->DoCmd($sql);
    }

    # Last, drop track_id and album_id
    #
    _report("dropping album_id");
    $sql = "ALTER TABLE product DROP COLUMN album_id";
    if ( !$dbo->DoCmd($sql) ) {
        _report( "error " . $dbo->LastErrorStr() );
        return;
    }

    _report("dropping track_id");
    $sql = "ALTER TABLE product DROP COLUMN track_id";
    if ( !$dbo->DoCmd($sql) ) {
        _report( "error " . $dbo->LastErrorStr() );
        return;
    }

    _report("product table has been altered");
}

sub _usage {
    print "\nusage: $0 -o original client_id -c client_id [-V]\n";
    print "\n";
    print "Arguments:\n";
    print "\t-o <client_id>\t\tThe client_id of the Raptor client (from which we'll copy some stuff)\n";
    print "\t-c <client_id>\t\tThe client_id of the client to process\n";
    print "\t-V <N>\t\t\tVerbosity level - 0 means no output\n";
}

sub _report {
    my ( $string, $verbosity ) = @_;
    $verbosity = 1 unless defined $verbosity;

    if ( $gVerbosityLevel >= $verbosity ) {
        print STDERR $string . "\n";
    }
}

# Pass dates in 'yyyy-mm-dd' format.
#
sub _parseCommandLine {
    my ($settings) = @_;

    my %opt;
    getopts( 'c:o:V:', \%opt );

    if ( !$opt{c} ) {
        _usage();
        exit(1);
    }
    $settings->{clientID} = $opt{c};

    if ( !$opt{o} ) {
        _usage();
        exit(1);
    }
    $settings->{origClientID} = $opt{o};

    if ( defined $opt{V} ) {
        $gVerbosityLevel = $opt{V};
    }
}
