#!/usr/bin/env perl

use warnings;
use strict;

use Getopt::Long;
use Cwd;

use lib "/cluster/bin/scripts";
use Encode;
use RAFile;
use HgAutomate;
use HgDb;

use vars qw/
    $opt_configDir
    $opt_verbose
    $opt_instance
    $opt_geoUser
    $opt_downloadDir
    /;

sub usage {
    print STDERR <<END;
usage: encodeMdbToDdf database composite var1 var2 ... varN
    -instance=s         Use ENCODE pipeline instance s (default prod).
    -configDir=dir      Path of configuration directory, containing metadata
                        .ra files (default: /hive/groups/encode/dcc/pipeline/encpipeline_prod/config/)
    -verbose=num        Set verbose level to num (default 1).
END
exit 1;
}

############################################################################
# Function

sub getObjMetadata {
    my ($db, $obj) = @_;
    my $results = $db->execute("SELECT var, val FROM metaDb WHERE obj = '$obj'");
    my %metadata = ();
    if($results) {
        while(my @row = $results->fetchrow_array()) {
            my $key = $row[0];
            my $value = $row[1];
            $metadata{$key} =  $value;
            #print "\t$key = $value\n";
        }
    }

    return %metadata;
}

sub getObjsMatching {
    my ($db, $var, $val) = @_;
    # get the list of objects matching var=val
    my $results = $db->execute("SELECT obj FROM metaDb WHERE var = \"$var\" and val = \"$val\"");
    my @objects = ();
    if($results) {
        while(my @row = $results->fetchrow_array()) {
            my $obj = $row[0];
            push @objects, $obj;
        }
    }

    return @objects;
}

sub getSameMetadata {
    my $field = shift;
    my @metadataList = @_;

    my %metadata;

    %metadata = %{$metadataList[0]};
    my $firstValue = $metadata{$field};
    for (my $i = 1; $i < scalar(@metadataList); ++$i) {
        %metadata = %{$metadataList[$i]};
        die "$firstValue != $metadata{$field}" unless $firstValue eq $metadata{$field};
    }
    return $firstValue;
}

############################################################################
# Main

my $now = time();
my $wd = cwd();
my $ok = GetOptions("instance=s",
                    "configDir=s",
                    "verbose=i"
                    );
# parse options
usage() if (!$ok);
usage() if (scalar(@ARGV) < 2);
# get options or set defaults
if (not defined $opt_instance) {
    $opt_instance = "prod";
}
my $configPath;
if (defined $opt_configDir) {
    if ($opt_configDir =~ /^\//) {
        $configPath = $opt_configDir;
    } else {
        $configPath = "$wd/$opt_configDir";
    }
} else {
    $configPath = "/hive/groups/encode/dcc/pipeline/encpipeline_$opt_instance/config/";
}
if(!(-d $configPath)) {
    die "configPath '$configPath' is invalid; Can't find the config directory\n";
}
if (not defined $opt_verbose) {
    $opt_verbose = 1;
}
HgAutomate::verbose(4, "Config directory path: \'$configPath\'\n");

my $database  = shift @ARGV;
my $compositeName = shift @ARGV;
my @selectedVars = ("view", "cell");
push @selectedVars, @ARGV;

# connect to the database and read the metadata table for the obj
my $dbHandle = HgDb->new(DB => $database);

# get the list of objects of this composite and store it in a set (hash)
my @objects = getObjsMatching($dbHandle, "composite", $compositeName);

# print the header
print "files";
for my $v (@selectedVars) {
    print "\t", $v;
}
print "\n";

# for each object
for my $obj (@objects) {
    my %metadata = getObjMetadata($dbHandle, $obj);
    # if it's a file,
    if (defined $metadata{"fileName"}) {
        my $filename = $metadata{"fileName"};
        # if the filename ends in .gz, remove it
        if (substr($filename, length($filename) - 3) eq ".gz") {
            $filename = substr($filename, 0, length($filename) - 3);
        }
        print $filename;
        # print the selected vars for this file
        for my $v (@selectedVars) {
            if (defined $metadata{$v}) {
                print "\t", $metadata{$v};
            } else {
                print "\t";
            }
        }
        print "\n";
    }
}
