#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#---------------------------------------------------------------
package BookPub::Catalog::Import::Process::Fetcher::FileHandler;
use strict;
use warnings;

use File::Path;
use Data::Dumper;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use Common::Assert;
use Common::Process;
use BookPub::DB::Item::CatalogImportItem::FTPFile;

use base 'Common::Process';

# This class is the base class for Fetcher::FileHandler objects.
# Exactly what the class hierarchy will look like remains to be determined.
# But, it's clear that every client will need to specify reasonably custom behavior.
#
# We'll probably need :
# - a 'zip file' class that can unzip files into a particular destination directory.
# - a 'onix file' class that knows to 'register' the file by making a CatalogImportFile entry
# -> Actually, we may implement that behavior in the Fetcher class.

# At the very least, this base class will know how to copy the file from the FTP site to
# the staging area, then do some sort of post-copy processing on it.

# I think all the heavy lifting (ftp transfers, unzipping, etc) should be implemented in the Fetcher class.
# The FileHandler objects simply embody the knowledge of what needs to be done in what sequence.

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

    $self->SUPER::_init(%args);

    $self->{_fetcher} = $args{fetcher};
    assert( $self->{_fetcher} );

    $self->{_remoteFile} = $args{remoteFile};
    assert( $self->{_remoteFile} );

    $self->{_localDirectory} = $args{localDirectory};
    assert( $self->{_localDirectory} );

    $self->{_localFileName} = $args{localFileName};
    assert( $self->{_localFileName} );

    return $self;
}

sub remoteFile {
    my ($self) = @_;
    return $self->{_remoteFile};
}

sub localFile {
    my ($self) = @_;
    return $self->{_localDirectory} . '/' . $self->{_localFileName};
}

sub download {
    my ($self) = @_;
    $self->_report( "BookPub::Catalog::Import::Process::Fetcher::FileHandler::download", 3 );

    $self->_retrieveRemoteFile();

    # !!! Not going to do this immediately anymore.
    # !!! Instead, we'll wait until the entire import has completed, then do it (if it was successful).
    $self->_archiveRemoteFile();
}

sub process {
    my ($self) = @_;
    $self->_report( "BookPub::Catalog::Import::Process::Fetcher::FileHandler::process", 3 );

    $self->_processLocalFile();
}

sub _retrieveRemoteFile {
    my ($self) = @_;
    $self->_report( "BookPub::Catalog::Import::Process::Fetcher::FileHandler::_retrieveLocalFile", 3 );

    #  Let's make sure the local directory exists.
    #
    if ( !-d $self->{_localDirectory} ) {
        File::Path::mkpath( $self->{_localDirectory} ) || die "ERROR - unable to create directory " . $self->{_localDirectory} . " : $!";
    }

    # By default, we copy the file straight over.
    #
    #    my $destination = $self->{_localDirectory} . '/' . $self->{_localFileName};
    my $destination = $self->localFile();

    $self->{_fetcher}->_ftpGet( $self->{_remoteFile}, $destination );

}

sub _processLocalFile {
    my ($self) = @_;

    assert( 0, 'override' );
}

# Rather than deleting the file from the ftp site, we move the file into a directory called '_archive'.
# This gives us an additional safety measure if we need to roll back, start over, etc.
#
# !!! New plan.  Now we'll just record the filenames of all the 'remote' files on the FTP site that
# !!! we handle.  Later, assuming the process completes, we'll archive them.
#
sub _archiveRemoteFile {
    my ($self) = @_;
    $self->_report( "BookPub::Catalog::Import::Process::Fetcher::FileHandler::_archiveRemoteFile", 3 );

    #    $self->_report("!!! not actually moving the file during development");

    #    $self->{_fetcher}->_ftpMoveToArchive($self->{_remoteFile});
    my $newFTPFile = BookPub::DB::Item::CatalogImportItem::FTPFile->Create(
        catalog_import_id => $self->{_fetcher}->_catalogImportID(),
        file_name         => $self->{_remoteFile},
    );
    $newFTPFile->save();
}

1;
