#!/usr/bin/perl
#< Perform automated FTP transfer, creating directories as required

# Input file (specified by -f) must NOT contain leading slashes

use strict;
use warnings;

use Getopt::Long;
use Net::FTP;

## External Test
#my $FTPHOST = "einstein.kw";
#my $FTPPASS = "nosuchpass";
#my $FTPUSER = "kevin";
#my $FTPROOT = "/data/www/test.zazzybob.kw/";
#my $FTPLOCALROOT = "/files/zazzybob.com/";

# Production
my $FTPHOST = "my.prod.server";
my $FTPPASS = "my.prod.pass";
my $FTPUSER = "my.prod.user";
my $FTPROOT = "/";
my $FTPLOCALROOT = "/files/zazzybob.com/";

my $FTP = undef;

my $O_FILE = "";
my $O_HELP = "0";
my $O_VERBOSE = "0";

my $E_ERROR = "1";
my $E_SUCCESS = "0";

sub display_help() {
   my $thisprog = "";
   $thisprog = $0;
   $thisprog =~ s#^,&/##;
   printf( "Usage: %s [-hv] -f <input_file>\n", $thisprog );
   printf( "           -f     Specify path to input file\n" );
   printf( "           -h     Print this help message\n" );
   printf( "           -v     Run in verbose mode\n" );
}

sub process_arguments() {
   GetOptions ( 'file=s' => \$O_FILE,
                'help' => \$O_HELP,
                'verbose+' => \$O_VERBOSE 
              ) or $O_HELP++;
   if ( $O_HELP > 0 ) {
      display_help;
      exit( $E_ERROR );
   }
   if ( $O_FILE eq "" ) {
      printf( STDERR "Error: Input file must be specified\n" );
      exit( $E_ERROR );
   } elsif ( ! -f $O_FILE ) {
      printf( STDERR "Error: Input file not found\n" );
      exit( $E_ERROR );
   }
}

sub initiate_connection() {
   $O_VERBOSE &&
      printf( "--> Attempting to open FTP connection to %s\n", $FTPHOST );
   $FTP = Net::FTP->new( $FTPHOST ) or
      die( "<-- Couldn't open FTP connection to $FTPHOST: $!" );
   $O_VERBOSE &&
      printf( "<-- FTP connection to %s ESTABLISHED\n", $FTPHOST );
   $O_VERBOSE &&
      printf( "--> Attempting to login as %s\n", $FTPUSER );
   $FTP->login( $FTPUSER, $FTPPASS ) or
      die( "<-- Login as $FTPUSER failed: $!" );
   $O_VERBOSE &&
      printf( "<-- Login to %s as %s SUCCESSFUL\n", $FTPHOST, $FTPUSER );
   #$FTP->cwd( $FTPROOT );
   #my @results = $FTP->ls;
   #foreach my $result ( @results ) {
   #   printf( "-->%s\n", $result );
   #}
}

sub terminate_connection() {
   $O_VERBOSE && 
      printf( "--> Closing FTP connection to %s\n", $FTPHOST );
   $FTP->quit or
       die( "<-- Could not close FTP connection to $FTPHOST\n" );
   $O_VERBOSE && 
      printf( "<-- FTP connection to %s CLOSED\n", $FTPHOST );
}

sub perform_transfer() {
   open( INFILE, "< $O_FILE" );

   while ( <INFILE> ) {
      chomp; 
      my $filepath = $_;
      my $localfile = $FTPLOCALROOT . $filepath;
      $O_VERBOSE && 
         printf( "--> Local file %s listed for deployment\n", $localfile );
      if ( -f $localfile ) {
         $O_VERBOSE &&
            printf( "<-- %s exists and ready for deployment\n", $localfile );
      } else {
         printf( STDERR "Error: %s does not exist\n", $localfile );
         exit( $E_ERROR );
      }
      $O_VERBOSE && 
         printf( "--> Attempting to CD to remote FTPROOT: %s\n", $FTPROOT );
      $FTP->cwd( $FTPROOT ) or
         die( "<-- CD to $FTPROOT failed: $!" ); 
      my @components = split ( /\//, $filepath );
      my $total_components = scalar( @components );
      my $component_counter = 1;
      foreach my $component ( @components ) {
         if ( $component_counter == $total_components ) {
            $O_VERBOSE && 
               printf( "--> Attempting to PUT %s\n", $component );
            $FTP->put( $localfile, $component ) or
               die( "<-- Could not PUT $component: $!\n" );
            $O_VERBOSE &&
               printf( "<-- %s SUCCESSFULLY DEPLOYED\n", $component );
         } else {
            $O_VERBOSE && 
               printf( "--> Attempting to CD to %s\n", $component );
            my $success = 1;
            $FTP->cwd( $component ) and $success = 0;
            if ( $success == 1 ) {
               $O_VERBOSE &&
                  printf( "<-- %s does not exist\n", $component ); 
               $O_VERBOSE && 
                  printf( "--> Attempting to MKDIR %s\n", $component );
               $FTP->mkdir( $component ) or 
                  die( "<-- Could not MKDIR $component: $!\n" );
               $O_VERBOSE && 
                  printf( "<-- Directory %s created\n", $component );
               $O_VERBOSE && 
                  printf( "--> Attempting to CD to %s\n", $component );
               $success = 1;
               $FTP->cwd( $component ) and $success = 0;
               if ( $success == 0 ) {
                  $O_VERBOSE &&
                     printf( "<-- CD into %s successful\n", $component );
               } else {
                  die( "<-- Could not create and CD into $component:$!\n" );    
               }
            } else {
               $O_VERBOSE &&
                  printf( "<-- CD into %s successful\n", $component );
            }
         }
         $component_counter++; 
      }
   }
   close( INFILE );
}

# main()

process_arguments;
initiate_connection;
perform_transfer;
terminate_connection;

exit( $E_SUCCESS );