package Business::BatchPayment::TD_EFT::Transport;

use File::Temp qw(tempdir);
use File::Slurp qw( read_file write_file );
use File::Copy;
use IPC::Run qw(run);
use Moose;
extends 'Business::BatchPayment::Transport::SFTP';

=head1 ATTRIBUTES

=over 4

=item encrypt_cmd

Path to the encrypt command, including any options.  The name of the 
file to encrypt will be passed on standard input, and the name of the 
destination file will be inserted after the first (whitespace-separated)
word of the command.  This is in deference to compx/Comm-Press/TDClient
conventions.

=item decrypt_cmd

Path to the decrypt command, as above.

=item encrypt_key

Path to the encryption key.  This will be copied to the temp directory
before running encrypt/decrypt commands.

=cut

has [ qw( encrypt_cmd encrypt_key decrypt_cmd ) ] => (
  is  => 'rw',
  isa => 'Maybe[Str]',
  required => 0,
);

sub upload {
  my $self = shift;
  my $path = $self->put_path;

  my $content = shift;

  # get the batch ID of the content
  # (questionable--on the one hand, upload isn't supposed to concern 
  # itself with the contents of the batch, but on the other hand it 
  # needs to know what to name the file.)
  my $id = substr($content, 20, 4);

  my $tmpdir = tempdir( CLEANUP => 1 );
  chdir($tmpdir);
  my $filename = 'update' . $id;
  warn "Writing temp file to $tmpdir/$filename\n" if $self->debug;
  write_file("$tmpdir/$filename", $content);
  if ( $self->encrypt_cmd ) {
    warn "Encrypting temp file.\n" if $self->debug;
    if ( $self->encrypt_key ) {
      copy($self->encrypt_key, "$tmpdir/encrypt.key")
        or die "Failed to read encryption key: $!\n";
    }
    my @cmd = split(/\s+/, $self->encrypt_cmd);
    # insert output file name into command line
    splice(@cmd, 1, 0, "$filename.cmp");
    # run(COMMMAND, STDIN, STDOUT)
    run(\@cmd, \$filename) or die "Failed to encrypt temp file: $!\n";
    $filename = "$filename.cmp";
  }
  warn "Uploading file to $path/$filename\n" if $self->debug;
  $self->sftp->setcwd($path);
  $self->sftp->put("$tmpdir/$filename", $filename);
  chdir('/');
}

sub download {
  my $self = shift;
  my $path = $self->get_path;

  my @batches;
  my $tmpdir = tempdir( CLEANUP => 1 );
  chdir($tmpdir);
  warn "Fetching list of return files from $path\n" if $self->debug;
  $self->sftp->setcwd($path);
  my $files = $self->sftp->ls('.', wanted => qr/^APXQA807/, names_only => 1);
  if ( !@$files ) {
    warn "No files found.\n" if $self->debug;
  }
  if ( $self->encrypt_key ) {
    copy($self->encrypt_key, "$tmpdir/encrypt.key")
      or die "Failed to read encryption key: $!\n";
  }
  FILE: foreach my $filename (@$files) {
    warn "Retrieving file $filename\n" if $self->debug;
    $self->sftp->get($filename, "$tmpdir/$filename");
    if ( $self->sftp->error ) {
      warn "failed to download $filename: ".$self->sftp->error;
      next FILE;
    }
    $filename = "$tmpdir/$filename";
    if ( $self->decrypt_cmd ) {
      my @cmd = split(/\s+/, $self->decrypt_cmd);
      splice(@cmd, 1, 0, "$filename.txt");
      if ( !run(\@cmd, \$filename) ) {
        warn "Failed to decrypt file: $!\n";
        next FILE;
      }
    }
    push @batches, read_file($filename);
  }
  chdir('/');
  @batches;
}

__PACKAGE__->meta->make_immutable;

1;
