#!/usr/bin/env perl

# this program injects a list of multi-file exposures into the db.
# the program takes a list of directory names (dir), and injects all
# dir/*.fits.  It takes the directory name as the exp_tag.  the user
# supplies a temporary telescope and instrument name.  these are used
# for informational purposes only until the registration step can
# determine the true telescope and instrument name from the image
# headers.

# this program should not fail because of the data format or the
# configuration, except for the very basic database setup.

use warnings;
use strict;

use IPC::Cmd 0.36 qw( can_run run );
use PS::IPP::Config qw( caturi );

use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );

my ($camera, $telescope, $dbname, $workdir, $path);
GetOptions(
	   'camera|c=s'    => \$camera,    # Camera used	      
	   'telescope|t=s' => \$telescope, # Telescope used      
	   'workdir=s'     => \$workdir,   # Database name	      
	   'path=s'        => \$path,	   # Working directory   
	   'dbname=s'      => \$dbname,	   # Path to data        
) or pod2usage( 2 );

pod2usage(
	  -msg => "Required options: --camera --telescope --workdir --path --dbname",
	  -exitval => 3,
	  ) unless defined $camera
    and defined $telescope
    and defined $workdir
    and defined $path
    and defined $dbname;

my $ipprc = PS::IPP::Config->new(); # IPP configuration

# Look for programs we need
my $missing_tools;
my $pxinject = can_run('pxinject')  or (warn "Can't find pxinject" and $missing_tools = 1);

if (scalar @ARGV == 0) {
    die "No exposures provided.\n";
}

# Inject new data into the database
my @classes;			# Names of the classes
my @files;			# What to add to the filename for each class
my $add_dir;			# Add directory name to get file name?

foreach my $exp_name ( @ARGV ) {
    my @files = <"$exp_name/*.fits">;
    my $Nfiles = scalar @files;

    my $command = "$pxinject -newExp";
    $command .= " -exp_name $exp_name";
    $command .= " -inst $camera";
    $command .= " -telescope $telescope";
    $command .= " -workdir $workdir";
    $command .= " -dbname $dbname" if defined $dbname;

    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
	run( command => $command, verbose => 1 );
    die "Unable to inject $exp: $error_code\n" if not $success;
    
    my @line = split(/\s+/, $$stdout_buf[0]); # The output line, containing the exposure tag
    my $exp_id = $line[2];	# The exposure tag

    my $class_id = 0;
    foreach my $filename (@files) {

	my $absfile = File::Spec->rel2abs( $filename );
	my $relfile = $ipprc->convert_filename_relative( $absfile );

	# XXX the class_id used here should be temporary : register should replace it with the true class_id
	my $command_imfile = "$pxinject -newImfile";
	$command_imfile .= " -exp_id $exp_id";
	$command_imfile .= " -exp_name $exp_name";
	$command_imfile .= " -class chip";
	$command_imfile .= " -class_id $class_id";
	$command_imfile .= " -uri $relfile";
	$command_imfile .= " -dbname $dbname" if defined ($dbname);
	
	my ( $success_imfile, $error_code_imfile, $full_buf_imfile, $stdout_buf_imfile, $stderr_buf_imfile ) = run( command => $command_imfile, verbose => 1 );
	die "Unable to inject $exp_name imfile: $error_code_imfile\n" if not $success_imfile;

	$class_id ++;
    }

    # finalize the exposure
    $command  = "$pxinject -updatenewExp";
    $command .= " -exp_id $exp_id";
    $command .= " -state run";
    $command .= " -dbname $dbname" if defined $dbname;

    ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
	run( command => $command, verbose => 1 );
    die "Unable to inject $exp: $error_code\n" if not $success;
}

END {
    my $status = $?;
system("sync") == 0
    or die "failed to execute sync: $!" ;
$? = $status;
}


__END__


