# -*-perl-*-

# $Id$

# Front-end to add, remove, or list limits in the db.

# $Log$
# Revision 1.4  2004/12/06 22:40:02  thomas
# [CSL #249207] add a pool update subcommand
#
# Revision 1.3  2003/06/09 14:45:12  thomas
# schema version of database
#
# Revision 1.2  2002/08/14 17:13:07  thomas
# 0.2.9 release
#
# Revision 1.1  2002/07/08 15:56:35  thomas
# 0.2.3 release
#
# Revision 1.1.1.1  2002/05/21 14:13:34  thomas
# sushi - backup to disk
#

package Sushi::Command::Pool;

use strict;
use Getopt::Long;

my %subs = (
	    add      => \&Sushi::GenDB::add,
	    list     => \&list,
	    update   => \&update,
	    del      => \&Sushi::GenDB::del,
	    help     => \&printhelp,
	    '--help' => \&printhelp,
	    '-h'     => \&printhelp
	   );

###############################################################################

sub main {
  my ($class) = shift;
  my $cmd = shift @ARGV;

  my $args = {};
  my $opts = {
	      print_headings => 1,
	      print_results => 1
	     };

  Getopt::Long::Configure ("bundling");
  my $res;
  if (!($res = GetOptions (
			   'storage_id|i=s', \$args->{storage_id},
			   'media_size|s=s', \$args->{media_size},
			   'media_type|t=s', \$args->{media_type},
			   'comment|c=s',    \$args->{comment},
			   'showused|u',     \$opts->{showused},
			  ))) {
    $main::log->error (&help);
    return 0;
  }

  defined ($ARGV[0]) and $args->{storage_id} = shift @ARGV;
  defined ($ARGV[0]) and $args->{media_size} = shift @ARGV;
  defined ($ARGV[0]) and $args->{media_type} = shift @ARGV;
  defined ($ARGV[0]) and $args->{comment} = shift @ARGV;

  $args->{media_size} = Sushi::Misc::sushiInt ($args->{media_size});

  if (defined $subs{$cmd}) {
    return $subs{$cmd} ($args, $opts, $::table_defs->{offline_pool});
  }
  $main::log->error("Bad limit sub-command specified\n");
  return;
}

###############################################################################

sub update {
  my ($args, $opts, $table_def) = @_;

  # Where clause -- only one row at a time...
  if (!defined $args->{storage_id}) {
    $main::log->error("pool update: storage id required.  Update skipped\n");
    return 0;
  }
  my ($col, $set);
  $set = {};
  foreach $col (@{$table_def->{columns}}) {
    $col->{col} eq 'storage_id' and next;
    defined ($args->{$col->{col}}) and $set->{$col->{col}} = $args->{$col->{col}};
  }

  my $nrows = Sushi::GenDB::update (
				    { storage_id => $args->{storage_id} },
				    {},
				    $set,
				    $table_def,
				   );
  return $nrows;
}


###############################################################################

sub list {
  my ($args, $opts, $table_def) = @_;

  my $pool = {};
  my $row;

  foreach my $row (@{Sushi::GenDB::fetch ($args, $opts, $::table_defs->{offline_pool})}) {
    $pool->{$row->{storage_id}} = $row;
  }

  if ($opts->{showused}) {
    foreach $row (@{Sushi::GenDB::fetch ({}, {}, $::table_defs->{view_results_offline})}) {
      if (!defined $pool->{$row->{storage_id}}) {
	$pool->{$row->{storage_id}} = {
				       storage_id => $row->{storage_id},
				      };
      }
      my $prow = $pool->{$row->{storage_id}};
      defined $prow->{used} or $prow->{used} = 0;
      if (!defined ($prow->{starttime}) ||
	  $row->{timestamp} < $prow->{starttime}) {
	  $prow->{starttime} = $row->{timestamp};
      }
      if (!defined $prow->{endtime} ||
	  $row->{timestamp} > $row->{endtime}) {
	  $prow->{endtime} = $row->{timestamp};
      }
      defined $row->{comp_size} and
	$pool->{$row->{storage_id}}->{used} += $row->{comp_size};
    }
  }

  # Print the headings if needed
  Sushi::GenDB::displayHeader ($opts, $table_def);

  # Get the rows and print them
  my $key;
  my $rows=0;
  foreach $key (sort keys %$pool) {
    Sushi::GenDB::displayRow ($opts, $table_def, $pool->{$key});
    $rows++;
  }

  Sushi::GenDB::displayTrailer ($opts, $table_def, $rows);

  return $rows;
}

	
###############################################################################

sub aliases {
  return ();
}

###############################################################################

sub printhelp {
  print help();
  return 1;
}

sub shortHelp {
  return "Add, delete or remove media from the offline pool";
}

sub help {
  my $help = <<__Eof__

pool\tadd <options>
\tdel <options>
\tupdate <options>
\tlist <options> [--showused|-u]
options: [(--storage_id|-i) <media identifier>]
\t[(--media_size|-s) <media size>]
\t[(--media_type|-t) disk]
\t[(--comment|-c) <comment>]
\t[<media identifier>] [<media size>] [disk] [<comment>]

Media size may be appended with a 'k', 'm', or 'g' 
  to specify space in kilobytes, megabytes, or gigabytes, respectively.

Update can update media_size, media_type, or comment on an existing
storage node in the offline pool.  storage_id is required for update
(thus only one node can be updated at a time).

--showused will list used space on each device (this takes awhile).

__Eof__
;
}

###############################################################################

1;
