#---------------------------------------------------------------
## ____                   _ _         ____  _
##|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
##| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
##|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
##|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
##            |___/             |___/
##
## Copyright (C) 2010 RoyaltyShare, Inc.      All Rights Reserved
##
## $Id$
##---------------------------------------------------------------

package BookPub::Tracker::Command::RSFTP;

use strict;
use warnings;

use Net::FTP;
use Net::SFTP::Foreign;
use File::Basename;

sub execute {

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

    my $host       = $args{FtpSite};
    my $username   = $args{Username};
    my $password   = $args{Password};
    my $targetDir  = $args{TargetDir};
    my $filePath   = $args{FilePath};
    my $protocol   = $args{Protocol};
    my $privateKey = $args{PrivateKey};
    my $type       = $args{Type};

    if ( lc($protocol) eq 'ftp' ) {

        my ($ftp) = {};

        $ftp = Net::FTP->new( $host, Timeout => 240 )
            or return "Error: Can't connect to $host\n";

        $ftp->login( $username, $password )
            or return "Error: Can't log in to $host\n";

        $ftp->cwd($targetDir)
            or return "Error: Can't change to $targetDir\n";

        $ftp->type($type);
        #    or return "Error: Can't set transfer type to $type\n";

        if ( $type eq 'binary' ) {
            $ftp->binary()
                or return "Error: Can't set ftp object to binary()\n";
        } else {
            $ftp->ascii()
                or return "Error: Can't set ftp object to ascii()\n";
        }

        $ftp->put($filePath)
            or return "Error: Can't put $filePath\n";

        $ftp->close;
        $ftp->quit;

        return "Success: File transferred successfully.";
    } elsif ( lc($protocol) eq 'sftp' ) {

        my $sftp;
        #$Net::SFTP::Foreign::debug = -1;

        if ( $host eq 'johnwiley.cleointegration.cloud' ) {
            $sftp = Net::SFTP::Foreign->new(
                $host,
                user       => $username,
                password   => $password,
                queue_size => 1,
                more       => [
                    -o => 'StrictHostKeyChecking no',
                    -o => 'PreferredAuthentications=password'
                ]
            );
        } elsif ($privateKey) {
            my $privateKeyPath = "/home/ec2-user/.ssh/dtmv/";

            $sftp = Net::SFTP::Foreign->new(
                $host,
                user     => $username,
                key_path => $privateKeyPath . $privateKey,
                timeout  => 240,
                more     => [ -o => 'StrictHostKeyChecking no' ]
            );
        } else {
            $sftp = Net::SFTP::Foreign->new(
                $host,
                user     => $username,
                password => $password,
                timeout  => 240,
                more     => [ -o => 'StrictHostKeyChecking no' ]
            );
        }

        $sftp->error and return "Error: Unable to establish SFTP connection to $host (" . $sftp->error . ")\n";
        #$sftp->die_on_error("Unable to establish SFTP connection");

        if ($targetDir) {
            $sftp->setcwd($targetDir) or return "Error: Unable to change to target directory: " . $sftp->error;
        }

        # transfer file, but not the permissions or timestamp
        my $targetPath = basename($filePath);
        $sftp->put($filePath, $targetPath, resume => 1, copy_perms => 0, copy_time => 0 ) or return "Error: File transfer failed: " . $sftp->error;

        return "Success: File transferred successfully.";
    } else {

        die "Protocol $protocol is not supported";

    }
}

sub _errorlog {
    print "Error: ";
    print @_;
    exit 0;
}

# A Perl module must end with a true value or else it is considered not to
# have loaded.  By convention this value is usually 1 though it can be
# any true value.  A module can end with false to indicate failure but
# this is rarely used and it would instead die() (exit with an error).
1;
