# -*-perl-*-

# $Id: Find.plm,v 1.2 2008/01/31 17:29:02 thomas Exp $

# Find the appropriate backups for a given atom

# $Log: Find.plm,v $
# Revision 1.2  2008/01/31 17:29:02  thomas
# [CSL #342884] sushi find --like doesn't work
#
# Revision 1.1  2007/02/07 17:21:30  thomas
# Find atoms in sushi
#
# Revision 1.1  2007/02/07 17:21:00  thomas
# Find atoms in sushi
#

package Sushi::Command::Find;

use strict;
use Getopt::Long;
use Time::localtime;

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

sub main {
  my ($class) = shift;

  my ($args, $atom, $key, $res);
  my ($opts) = {
		print_headings => 1,
		before => time,
		since  => time - 60*60*24*30*8,
	       };
  my ($help) = 0;

  Getopt::Long::Configure ("bundling");
  if (!($res = GetOptions (
			   'schedule_group|g=s',  \$args->{schedule_group},
			   'type|t=s',            \$args->{type},
			   'name|n=s',            \$args->{name},
			   'id|i=s',              \$args->{id},
			   'state|s=s',           \$args->{state},
			   'level|l=s',           \$args->{level},
			   'debug|d=s',           \$args->{debug},
			   'offline',             \$opts->{print_offline},
			   'like',                \$opts->{like},
			   'since=s',             \$opts->{since},
			   'before=s',            \$opts->{before},
			   'help|h',              \$help
			  ))) {
    $main::log->error (&help);
    return 0;
  }

  $help and return printhelp();

  foreach ('before', 'since') {
    my $foo = Sushi::Misc::date2secs ($opts->{$_});
    die "Date $opts->{$_} unparsed!" unless defined $foo;
    $opts->{$_} = $foo;
  }

  defined ($ARGV[0]) and $args->{schedule_group} = shift @ARGV;
  defined ($ARGV[0]) and $args->{type} = shift @ARGV;
  defined ($ARGV[0]) and $args->{name} = shift @ARGV;

  my ($row, $do, $type, $name, $history, @backups, $i);
  # Use GenDB::fetch to process --like
  foreach $row (@{Sushi::GenDB::fetch (
                                       $args,
                                       $opts,
                                       $::table_defs->{atom})}) {
    $do->{$row->{type}}->{$row->{name}} = 1;
  }

  foreach $type (sort keys %$do) {
    foreach $name (sort keys %{$do->{$type}}) {
      $args = {
	       type => $type,
	       name => $name,
	      };
      $history = Sushi::Atom->readHistoryOffline ($args,$opts);
      return printhelp() unless (defined ($history) && ref ($history));
      # Ignore zero-row results
      next unless @$history;

      print "Backup information for $type:$name\n\n";

      # Scan through records
      foreach (sort {$a->{timestamp} <=> $b->{timestamp} or $a->{write_time} <=> $b->{write_time}} @$history) {
	next unless $_->{result} eq 'Success';
	next unless $_->{timestamp} > $opts->{since};
	next unless $_->{timestamp} < $opts->{before};
	if (defined $_->{disposition}) {
	  next unless ($_->{on_disk} eq 'Yes' || $_->{disposition} eq 'Available');
	} else {
	  next unless ($_->{on_disk} eq 'Yes');
	}
	# Set this level and clear all higher levels
	$backups[$_->{level}] = $_;
	for ($i=$_->{level}+1 ; $i<@backups ; $i++) {
	  delete $backups[$i];
	}
      }

      Sushi::GenDB::displayHeader (
				   $opts,
				   $::table_defs->{atom_history},
				  );
      foreach (@backups) {
	Sushi::GenDB::displayRow (
				  $opts,
				  $::table_defs->{atom_history},
				  $_,
				 );
      }
      Sushi::GenDB::displayTrailer (
				    $opts,
				    $::table_defs->{atom_history},
				    scalar @backups,
				   );
    }
  }
  return 0;
}

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

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

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

sub shortHelp {
  return "Display most recent backups for an atom";
}

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

sub help {
  my $help = <<__Eof__

find <options>

options: [(--schedule_group|-s) <group>] [(--type|-t) <type>] \\
\t[(--name|-n) <atom name>] [(--id|-i) <atom id>] \\
\t[--offline] [--like] [--before <date>] [--since <date>] \\
\t[<group> [<type> [<name>]]]

Print the most recent atoms at each level for the specified atom.

'find --like ...' will do sql pattern matching ('like operator') on any
parameter containing the '%' character.  For example, the command

find -n pongo\%:/ --like

will print the most recent epoch and incremental for pongo's '/' partition.

'--before <date>' will only consider backups before the given date.

'--since <date>' will only consider backups after the given date.

'--offline' will include information about offline backups.

__Eof__
;
}

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

1;
