#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2011 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------
package BookPub::Sale::Feed::SaleFeedFileList::Missing;
use strict;
use warnings;

use Data::Dumper;

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

use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::SaleFeedFile;
use BookPub::Sale::Feed::SaleFeedFile;
use BookPub::Sale::Feed::SaleFeedService;
use BookPub::Sale::Feed::SaleFeedList;
use BookPub::Sale::Feed::SaleFeed;

use BookPub::RDAS::Request::SaleFeedFileList;

use base 'BookPub::Sale::Feed::SaleFeedFileList';

sub _init {
    my $self = shift;
    my %args = @_;

    $self->{_saleFeedServiceID} = $args{saleFeedServiceID};
    $self->{_saleFeedID}        = $args{saleFeedID};

    $self->_populateMissingFiles();

    return $self->SUPER::_init(@_);
}

sub period { shift->{_period} }

sub _getCollection {
    my ( $self, %args ) = @_;

    return $args{serviceID}
      ? BookPub::DB::Item::SaleFeedFile->GetAllMissingBySaleFeedServiceID( $self->saleFeedServiceID )
      : BookPub::DB::Item::SaleFeedFile->GetAllMissingBySaleFeedID( $self->saleFeedID );
}

sub _getObj {
    my ( $self, $dbItem ) = @_;
    assert($dbItem);

    return BookPub::Sale::Feed::SaleFeedFile->new( dbItem => $dbItem, readOnly => 1 );
}

# Find all missing sales files.  This is calculated using the period (# of days a sales file covers),
# and the first date we actually see a file.  If no files have been downloaded we do nothing.
sub _populateMissingFiles {
    my $self              = shift;
    my $saleFeedServiceID = $self->saleFeedServiceID();

    assert( $self->saleFeedServiceID || $self->saleFeedID );

    if ($saleFeedServiceID) {
        my $feeds = new BookPub::Sale::Feed::SaleFeedList( saleFeedServiceID => $saleFeedServiceID );
        foreach my $feed ( @{ $feeds->{SaleFeed} } ) {
            $self->_populateMissingFeed($feed);
        }
    } else {
        my $feed = new BookPub::Sale::Feed::SaleFeed( saleFeedID => $self->saleFeedID );
        $self->_populateMissingFeed($feed);
    }

}

sub _populateMissingFeed {
    my $self = shift;
    my $saleFeed = shift || die;

    die "Sale feed not found" unless ( $saleFeed->SaleFeedID );

    unless ( $saleFeed->Status eq 'active' ) {
        Log->notice( "Ignoring feed (id: " . $saleFeed->SaleFeedID . ") because status is not 'active'" );
        return;
    }

    my $date = $saleFeed->getStartingMissingDate() || return;

    my ( $startDate, $endDate ) = $self->_getDates($date);
    my $iteratorDate = $startDate;
    my $today        = Common::Date->now();

    unless ($startDate) {
        Log->warn("No reporting interval set.  Not reporting missing files");
        return;
    }

    while ( $iteratorDate < $today ) {
        Log->debug("Iterate missing check.  new S: $startDate E: $endDate I: $iteratorDate");

        if ( $iteratorDate eq $startDate ) {
            Log->info("Checking for missing file.  Start Date: $startDate");

            my $file =
              new BookPub::Sale::Feed::SaleFeedFile( saleFeedID => $saleFeed->SaleFeedID, startDate => "$startDate",
                endDate => "$endDate" );

            unless ( $file && $file->SaleFeedFileID ) {
                if ( $endDate < $today ) {
                    $file->save();
                    $file->updateStatus('missing');
                }
            }
        }

        $iteratorDate->addDays(1);
        ( $startDate, $endDate ) = $self->_getDates($iteratorDate);
    }
}

sub _getDates {
    my $self = shift;
    my $date = shift || die;

    my $startDate = Common::Date->new($date);
    my $endDate   = Common::Date->new($date);

    if ( !$self->frequency ) {
        return;
    } elsif ( $self->frequency eq 'daily' ) {
        return ( $startDate, $endDate );
    } elsif ( $self->frequency eq 'weekly' ) {
        $endDate->addDays(7);
        return ( $startDate, $endDate );
    } elsif ( $self->frequency eq 'monthly' ) {
        return ( new Common::Date( $startDate->monthBegin ), new Common::Date( $startDate->monthEnd ) );
    } elsif ( $self->frequency eq 'quarterly' ) {
        return ( new Common::Date( $startDate->quarterBegin ), new Common::Date( $startDate->quarterEnd ) );
    } elsif ( $self->frequency eq 'yearly' ) {
        return ( new Common::Date( $startDate->yearBegin ), new Common::Date( $startDate->yearEnd ) );
    } else {
        die "Unknown frequency '" . $self->frequency . "'";
    }
}

sub frequency {
    my $self = shift;

    return $self->{_frequency} if ( $self->{_frequency} );

    my $service =
      new BookPub::Sale::Feed::SaleFeedService( saleFeedID => $self->saleFeedID, saleFeedServiceID => $self->saleFeedServiceID );
    my $request = BookPub::RDAS::Request::SaleFeedFileList->GetRequestObject(
        $service->ServiceID,
        saleFeedServiceID => $service->SaleFeedServiceID,
        saleFeedID        => $self->saleFeedID
    );

    $self->{_frequency} = $request->reportFrequency();
    return $self->{_frequency};
}

1;
