#!/usr/bin/perl
#------------------------------------------------------------
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
use strict;

use Getopt::Std;
use Data::Dumper;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';

use BookPub::Sale::Match;
use BookPub::DB::Item::BestSellerBook;
use BookPub::DB::Item::BestSellerBookProduct;
use BookPub::DB::Item::BestSellerFormatType;
use BookPub::DB::Item::BestSellerList;
use BookPub::DB::Item::BestSellerMonitor;

use Common::NumericFormat;
use Common::Log;
use Common::RSApp;
use Common::Client;
use Common::DB::Item::Client;

Common::Log::Print(" - running with args '@ARGV'");

my %options;
parseCommandLine( \%options );
my $clientID = $options{clientID};

usage("missing client_id") unless ( defined $clientID );

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

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

    Common::Log::Print("Updating best sellers for client id $clientID");

    my $matcher = BookPub::Sale::Match->new( client_id => $clientID );

    # Now we need to scan the best sellers list in RSCOMMON
    # and try to match them to this client's catalog.

    Common::Log::Print("Fetching best seller lists");
    my $allLists = BookPub::DB::Item::BestSellerList->GetAll();
    while ( $allLists->hasNext() ) {
        my @excludedIDs;
        my $list   = $allLists->next();
        my $listID = $list->best_seller_list_id;

        my $allBooks = BookPub::DB::Item::BestSellerBook->GetAllCurrentByListID($listID);
        while ( $allBooks->hasNext() ) {
            my $book = $allBooks->next();

            # Unless we have a title and at least one ISBN, there's no point in trying to match.
            if ( $book->title && ( $book->isbn13 || $book->isbn10 ) ) {

                my $matches = {};
                my %bookHash;
                $bookHash{r_isbn13}     = $book->isbn13;
                $bookHash{r_isbn10}     = $book->isbn10;
                $bookHash{r_title}      = $book->title;
                $bookHash{r_subtitle}   = '';
                $bookHash{r_author}     = $book->author;
                $bookHash{product_type} = '';

                $matches = $matcher->get_book_matches( \%bookHash );

                my $numProducts = scalar keys %$matches;
                Common::Log::Print("Matched product count: $numProducts");

                for my $productID ( keys %$matches ) {
                    my $match       = $matches->{$productID};
                    my $matchStatus = $match->{status};

                    if ( $matchStatus eq 'match' ) {
                        my $bestSeller;

                        $bestSeller = BookPub::DB::Item::BestSellerBookProduct->Lookup(
                            best_seller_list_id => $listID,
                            product_id          => $productID,
                            rank                => $book->rank,
                            status              => 'current',
                        );

                        if ( !$bestSeller ) {

                            # Create new entry
                            $bestSeller = BookPub::DB::Item::BestSellerBookProduct->Create(
                                best_seller_list_id => $listID,
                                product_id          => $productID,
                                rank                => $book->rank,
                                status              => 'current',
                            );
                            $bestSeller->save();
                        }

                        # Populate/update the last verified field.
                        $bestSeller->UpdateLastVerified( id => $bestSeller->best_seller_book_product_id );

                        Common::Log::Print("Matching to product $productID");

                        push( @excludedIDs, $bestSeller->best_seller_book_product_id );
                    }
                }

            }

        }

        # Now for a little maintenance.
        # Any entries that we didn't just update will now be marked as 'old'.
        Common::Log::Print("Marking best sellers as old for list $listID");
        BookPub::DB::Item::BestSellerBookProduct->MarkCurrentAsOld( list_id => $listID, excluded_ids => \@excludedIDs );
    }

}

sub parseCommandLine {
    my ($settings) = @_;

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

    if ( !$opt{c} ) {
        usage();
        exit(1);
    }

    $settings->{clientID} = $opt{c};
}

sub usage {
    print STDERR "\nusage: $0 -c <client_id>\n";
    print STDERR "\n";
    print STDERR "Arguments:\n";
    print STDERR "\t-c <client_id>\t\tThe client_id of the client to process (or ALL for all clients)\n";
}

