package BookPub::RDAS::Request::POSData::Amazon;

use Data::Dumper;

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

use lib '/app/tools/rdas/lib';
use RDAS::Fetcher::FTP;

use lib '/app/tools/bookpub/lib';
use BookPub::RDAS::Form::POSData::File::Amazon;
use BookPub::RDAS::Response::POSData::Amazon;
use BookPub::ServiceCredential;

use base 'BookPub::RDAS::Request::POSData';

use constant kFTPServer => 'kcm.amazon-digital-ftp.com';

sub reports { shift->{_reports} }

sub _getResponseObject {
    my $self = shift;
    return new BookPub::RDAS::Response::POSData::Amazon( reports => $self->reports, reportDate => $self->reportDate, @_ );
}

sub _getFetchObject {
    my $self = shift;

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

    $self->{_fetcher} = new RDAS::Fetcher::FTP( server => kFTPServer );

    return $self->{_fetcher};
}

sub fetch {
    my $self = shift;
    $self->{_error} = undef;

    # Login
    unless ( $self->_login() ) {
        Log->error("Authentication failed");
        return;
    }

    # Now that all the initialization work is done lets actually do some real work
    unless ( $self->_storeMissingReports() ) {
        return;
    }

    return 1;
}

sub _credentials {
    my $self = shift;

    unless ( $self->{_credentials} ) {
        my $serviceID = $self->_getResponseObject()->serviceID();
        my $cred = new BookPub::ServiceCredential( serviceID => $serviceID );
        if ( $cred && $cred->Username && $cred->Password ) {
            $self->{_credentials} = [ $cred->Username, $cred->Password ];
        }
    }

    if ( $self->{_credentials} ) {
        return @{ $self->{_credentials} };
    } else {
        die "No login credentials";
    }
}

sub _login {
    my $self = shift;
    my ( $uname, $passwd ) = $self->_credentials();

    Log->notice("Logining in to FTP server");

    my $fetcher = $self->_getFetchObject();
    return $fetcher->login( $uname, $passwd );
}

sub _storeMissingReports {
    my $self = shift;

    Log->notice(" + Starting report download process");

    my @files = $self->_getReportFiles();
    Log->notice(" No new files to download.");

    return unless (@files);

    foreach my $file (@files) {
        return unless ( $self->_downloadSalesReport($file) );
    }

    return 1;
}

sub _getReportFiles {
    my $self = shift;
    my @result;
    my $fetcher = $self->_getFetchObject();
    my @files   = $fetcher->ls();
    my $reportDate;

    Log->debug("Files: @files");

    if ( $self->reportDate ) {
        $reportDate = new Common::Date( $self->reportDate );
    }

    foreach my $file (@files) {
        Log->debug(" - Attempting to parse filename: $file");
        my ( $year, $month, $day ) = $file =~ /seller_of_record_(\d{4})(\d{2})(\d{2})/;

        next unless ( $year && $month && $day );

        my $startDate = new Common::Date("$year-$month-$day");
        my $endDate   = $startDate->clone->addDays(6);

        Log->debug("   -- Start: $startDate");
        Log->debug("   -- end: $endDate");

        if ($reportDate) {
            Log->debug("   -- Report date: $reportDate");
            return $file if ( $reportDate >= $startDate && $reportDate <= $endDate );
        }

        else {
            if ( !$self->feed->isPassedStartDate($startDate) ) {
                Log->info("  -- Ignoring file $startDate, not passed start date");
            }

            elsif ( !$self->feed->isNew($startDate) ) {
                Log->info("  -- Ignoring file $startDate, is older than last download");
            }

            else {
                Log->info("  -- Adding file $file");
                push( @result, $file );
            }
        }
    }

    return @result;
}

sub _downloadSalesReport {
    my $self       = shift;
    my $file       = shift || return;
    my $reportDate = $self->_getReportDate($file);

    Log->notice("Starting sales report download process for $file");

    my $fetcher = $self->_getFetchObject();

    my $content = $fetcher->get($file);

    if ($content) {
        $self->{_reports}->{$reportDate} =
          new BookPub::RDAS::Form::POSData::File::Amazon( filename => $file, content => $content, startDate => $reportDate );
    } else {
        Log->error("  -- Failed download of report $file");
        return;
    }

    return 1;
}

sub _getReportDate {
    my $self     = shift;
    my $filename = shift;

    assert($filename);

    die "Could not determine report date from filename: $filename"
      unless ( $filename =~ /seller_of_record_(\d{4})(\d{2})(\d{2})_/ );

    my ( $year, $month, $day ) = ( $1, $2, $3 );

    return $year && $month && $day ? sprintf( "%04d-%02d-%02d", $year, $month, $day ) : undef;
}

1;
