package Storage::TarBundle;

use strict;
use Storage::Bundle;
use AgentConfig;
use vars qw|@ISA $FreeBSD|;

@ISA=qw|Storage::Bundle|;

$FreeBSD = isFreeBSD();

sub isFreeBSD {
  my $os = `uname -s`;
  chomp($os);
  return ($os eq 'FreeBSD');
}

sub _init {
  my ($self, %options) = @_;
  $self->SUPER::_init(%options);

  $self->{follow_symlinks} = 1 if defined $options{follow_symlinks};

  $self->{add_file} = [];
  if (exists $options{add_file}) {
    push @{$self->{add_file}}, $options{add_file};
  }

  if (exists $options{include}) {
    $self->{include} = $self->fileListToFile($options{include});
  }
  if (exists $options{exclude}) {
    $self->{exclude} = $self->fileListToFile($options{exclude});
  }
  if (exists $options{no_recursion}) {
    $self->{no_recursion} = 1;
  }

  $self->{include_hidden_files} = 1 if defined $options{include_hidden_files};

  return -d $self->{srcdir};
}

sub fileListToFile {
  my ($self, $fileList) = @_;

  #FIXME: detect who is passing non-chomped filenames
  chomp @{$fileList};

  my @list;
  foreach my $file ( @{$fileList} ) {
    if ( substr($file,0,1) eq "-" ) {
      push @{$self->{add_file}}, $file;
    }
    elsif ( $file ne '' ) {
      push @list, $file;
    }
  }

  if ( @list ) {
    my $fileName = POSIX::tmpnam();
    open FILELIST, ">$fileName";
    foreach my $file ( @list ) {
      print FILELIST "$file\n";
    }
    close FILELIST;
    return $fileName;
  }
  return;
}

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

  # FIXME: check tar presence
  my $tar = AgentConfig::tarBin();

  # Explicit -f - here because FreeBSD requires it
  my $cmd = "$tar -f - -c";

  $cmd .= " -h" if exists $self->{follow_symlinks};

  # FIXME: --ignore-failed-read

  $cmd .= " --no-recursion" if exists $self->{no_recursion};  

  if ( defined $self->{exclude} ) {
    $cmd .= " --anchored ";
    $cmd .= " -X '$self->{exclude}'";
  }
  
  if ( defined $self->{include} ) {
    $cmd .= " -T '$self->{include}'";
  } 
  if ( @{$self->{add_file}} ) {
    foreach my $file ( @{$self->{add_file}} ) {
      $cmd .= " --add-file='$file'";
    }
  }
  if ( ( !defined $self->{include} ) && ( !(@{$self->{add_file}}) ) ) {
    # When using .(dot) tar doesn't omit hidden files (i.e.starting with dot)
    # All files in archive are preceeded with './'
    # Tar archive contains:
    #     ./
    #     ./file1
    #     ./.file2
    #     ./directory1
    #     ./.directory2
    #     ./directory1/file3
    #     ./directory1/.file4
    # As a side effect, tar does backup owner, ownergroup and perms of top-level directory
    if (exists $self->{include_hidden_files}) {
      $cmd .= " .";
    }
    # When using *(asterisk) tar does omit hidden files in top directory only
    # All files in archive arent' preceeded with ./
    #     file1
    #     directory1
    #     directory1/file3
    #     directory1/.file4
    else {
      $cmd .= " *";
    }
  }

  if (defined $self->{sysuser}) {
    if( $FreeBSD ) {
      return 'su -m '. $self->{sysuser} . " -c \"" . $cmd . "\"";
    }
    else {
      my $sh = AgentConfig::shellBin();
      return 'su '. $self->{sysuser} . " --shell $sh -c \"" . $cmd . "\"";
    }
  }
  else {
    return $cmd;
  }
}

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

  unlink($self->{include}) if exists $self->{include};
  unlink($self->{exclude}) if exists $self->{exclude};

  $self->SUPER::cleanup();
}


1;