#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2011 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------
package BookPub::RDAS::Process::ProductReport;

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

use lib '/app/tools/bookpub/lib';
use BookPub::Catalog::ProductServiceUrl;
use BookPub::Catalog::Product::Book;
use BookPub::Catalog::ProductFormat;
use BookPub::Catalog::Book::WithAuthor;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Availability;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::CoverArt;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Failure;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Metadata;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Price;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Rank;

use base 'BookPub::RDAS::Process';

sub _options {
    {
        client_id => {
            short       => 'c',
            required    => 1,
            description => 'Limit to this client id',
            parameter   => 'i'
        },
        service_id => {
            short       => 's',
            required    => 1,
            description => 'Limit to this service id',
            parameter   => 'i'
        },
        product_id => {
            short       => 'p',
            description => 'Limit to this product id',
            parameter   => 'i'
        },
        count => {
            short       => 'n',
            description => 'Only fetch/generate n urls',
            parameter   => 'i'
        },
        service_list => {
            short       => 'y',
            description => 'List all monitored services',
        },
        current => {
            description => 'Only report products that have fetched information',
        },
    };
}

sub _processService {
    my $self = shift;
    my $serviceID = shift || die;

    Log->debug("** Begin service process, Service ID: $serviceID");

    $self->_printHeader();
    foreach my $product ( $self->_productList($serviceID) ) {
        Log->info( " - Fetching info for product " . $product->ProductID );

        $self->_processProduct( $serviceID, $product->ProductID );
    }
}

sub _processProduct {
    my $self      = shift;
    my $serviceID = shift;
    my $productID = shift;

    assert($serviceID);
    assert($productID);

    $self->_printLine( $productID, $serviceID );

}

sub _productList {
    my $self      = shift;
    my $serviceID = shift;
    my $current   = $self->param('current');

    my $productID = $self->param('product_id');
    my $limit     = $self->param('count');

    return new BookPub::Catalog::Product::Book( productID => $productID ) if ($productID);

    my $ebookOnly;
    unless ($ebookOnly) {
        my $request = BookPub::RDAS::Request::ProductPrice->GetRequestObject($serviceID);
        $ebookOnly = 1 unless ( $request->includePhysicalProducts() );
    }

    my $collection = BookPub::DB::Item::BookProduct->GetAllWithLimit(
        serviceID => $serviceID,
        ebookOnly => $ebookOnly,
        limit     => $limit,
        order     => 'DESC',
        current   => $current
    );

    Log->debug("* Get list of all products");

    my @list;

    while ( my $dbitem = $collection->next() ) {
        push( @list, new BookPub::Catalog::Product::Book( dbItem => $dbitem ) );
    }

    return @list;
}

sub _printLine {
    my $self      = shift;
    my $productID = shift;
    my $serviceID = shift;

    assert($serviceID);
    assert($productID);

    my $product = new BookPub::Catalog::Product::Book( productID => $productID );
    my $format = new BookPub::Catalog::ProductFormat( bookFormatID => $product->BookFormatID );
    my $book = new BookPub::Catalog::Book::WithAuthor( bookID => $product->BookID );
    my $url = new BookPub::Catalog::ProductServiceUrl( productID => $productID, serviceID => $serviceID );
    my $availability =
      new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Availability( productID => $productID, serviceID => $serviceID );
    my $coverArt =
      new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::CoverArt( productID => $productID, serviceID => $serviceID );
    my $failure = new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Failure( productID => $productID, serviceID => $serviceID );
    my $metadata =
      new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Metadata( productID => $productID, serviceID => $serviceID );
    my $price = new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Price( productID => $productID, serviceID => $serviceID );
    my $rank = new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Rank( productID => $productID, serviceID => $serviceID );

    no warnings;

    my @row = (
        $product->ProductID, $product->BookID, $product->ISBN13(), $format->asString(), $book->Title, $book->Subtitle,
        $book->AuthorName,   $url->URL,        $url->Note
    );

    push( @row, $availability ? $availability->Availability() : undef );
    push( @row, $failure ? ( $failure->Code(), $failure->Failure() ) : ( undef, undef ) );
    push( @row, $rank ? $rank->Rank() : undef );
    push( @row, $price ? ( $price->Price(), $price->CurrencyCode() ) : ( undef, undef ) );
    push(
        @row,
        $metadata
        ? (
            $metadata->Title(), $metadata->Subtitle(), $metadata->Format(), $metadata->Authors,
            $metadata->Imprint, $metadata->ISBN10,     $metadata->ISBN13,   $metadata->ASIN
          )
        : ( undef, undef, undef, undef, undef, undef, undef, undef )
    );
    push( @row, $coverArt ? $coverArt->URL() : undef );

    print join( "\t", @row ) . "\n";
}

sub _printHeader {
    my $self = shift;

    my @row = (
        'Product ID',
        'Book ID',
        'ISBN13',
        'Catalog Format',
        'Catalog Title',
        'Catalog Subtitle',
        'Catalog Authors',
        'Product Page',
        'Note',
        'Available',
        'Failure Code',
        'Failure Message',
        'Rank',
        'Price',
        'Currency Code',
        'Title',
        'Subtitle',
        'Format',
        'Authors',
        'Imprint',
        'ISBN 10',
        'ISBN 13',
        'ASIN',
        'Cover Art URL',
    );

    print join( "\t", @row ) . "\n";
}
1;
