#!perl
use strict;
use Data::Dumper;
use Carp;

#
# This is a SAS Component
#

=head1 fids_to_regulon_data





Example:

    fids_to_regulon_data [arguments] < input > output

The standard input should be a tab-separated table (i.e., each line
is a tab-separated set of fields).  Normally, the last field in each
line would contain the identifer. If another column contains the identifier
use

    -c N

where N is the column (from 1) that contains the subsystem.

This is a pipe command. The input is taken from the standard input, and the
output is to the standard output.

=head2 Documentation for underlying call

This script is a wrapper for the CDMI-API call fids_to_regulon_data. It is documented as follows:

  $return = $obj->fids_to_regulon_data($fids)

=over 4

=item Parameter and return types

=begin html

<pre>
$fids is a fids
$return is a reference to a hash where the key is a fid and the value is a regulons_data
fids is a reference to a list where each element is a fid
fid is a string
regulons_data is a reference to a list where each element is a regulon_data
regulon_data is a reference to a hash where the following keys are defined:
	regulon_id has a value which is a regulon
	regulon_set has a value which is a fids
	tfs has a value which is a fids
regulon is a string

</pre>

=end html

=begin text

$fids is a fids
$return is a reference to a hash where the key is a fid and the value is a regulons_data
fids is a reference to a list where each element is a fid
fid is a string
regulons_data is a reference to a list where each element is a regulon_data
regulon_data is a reference to a hash where the following keys are defined:
	regulon_id has a value which is a regulon
	regulon_set has a value which is a fids
	tfs has a value which is a fids
regulon is a string


=end text

=back

=head2 Command-Line Options

=over 4

=item -c Column

This is used only if the column containing the subsystem is not the last column.

=item -i InputFile    [ use InputFile, rather than stdin ]

=item -h

Display a list of the fields available for use.

=item -fields field-list

Choose a set of fields to return. Field-list is a comma-separated list of
strings. The following fields are available: regulon_id, regulon_set, tfs.


=back

=head2 Output Format

The standard output is a tab-delimited file. It consists of the input
file with extra columns added.

Input lines that cannot be extended are written to stderr.

=cut

my @all_fields = ( 'regulon_id', 'regulon_set', 'tfs' );
my %all_fields = map { $_ => 1 } @all_fields;


my $usage = "usage: fids_to_regulon_data [-h] [-c column] [-a | -f field list] < input > output";

use Bio::KBase::CDMI::CDMIClient;
use Bio::KBase::Utilities::ScriptThing;

my $column;
my @fields;
my $a;
my $f;
my $show_fields;

my $input_file;

my $kbO = Bio::KBase::CDMI::CDMIClient->new_for_script('c=i' => \$column,
						"a"   => \$a,
						"h"   => \$show_fields,
						"show-fields" => \$show_fields,
						"fields=s"    => \$f,
					        'i=s' => \$input_file);
if (! $kbO) { print STDERR $usage; exit }

if ($show_fields)
{
    print STDERR "Available fields: @all_fields\n";
    exit 0;
}
if ($a && $f) { print STDERR $usage; exit 1 }

if ($a)
{   
    @fields = @all_fields;
}
elsif ($f) {
    my @err;
    for my $field (split(",", $f))
    {   
        if (!$all_fields{$field})
        {   
            push(@err, $field);
        }
        else
        {   
            push(@fields, $field);
        }
    }
    if (@err)
    {   
        print STDERR "fids_to_regulon_data: unknown fields @err. Valid fields are: @all_fields\n";
        exit 1;
    }
} else {
    print STDERR $usage;
    exit 1;
}

my $ih;
if ($input_file)
{
    open $ih, "<", $input_file or die "Cannot open input file $input_file: $!";
}
else
{
    $ih = \*STDIN;
}

while (my @tuples = Bio::KBase::Utilities::ScriptThing::GetBatch($ih, undef, $column)) {
    my @h = map { $_->[0] } @tuples;

    my $h = $kbO->fids_to_regulon_data(\@h);
    for my $tuple (@tuples) {
        #
        # Process output here and print.
        #
        my ($id, $line) = @$tuple;
        my $v = $h->{$id};

        if (! defined($v))
        {
            print STDERR $line,"\n";
        }
        elsif (ref($v) eq 'ARRAY')
        {
            foreach my $row (@$v)
            {
		my @ret;
		foreach my $field (@fields) {
		    if (ref($row->{$field}) eq 'ARRAY') {
			    push (@ret, join (",", @{$row->{$field}}));
		     } else {
			    push(@ret, $row->{$field}); 
		     }
		}
	 	    my $out = join("\t", @ret);
		    print "$line\t$out\n";
            }
        }
        else
        {
            print "$line\n";
        }
    }
}
