#!/usr/local/bin/perl -I../lib -w
 
#-----------------------------------------------------------------------

=head1 NAME

B<query> - Query the cube.

=head1 SYNOPSIS

 query 
    [-help] |
    [-version] |
    [-verbose] 
    [-databaseName databaseName] 
    [-databaseMode GDBM | DBM | BSD | SMALLDBM] 
    unit@measure, unit@measure, ...

=head1 DESCRIPTION

B<query> queries the cube.  We assume that units and measures do 
not contain commas or at symbols.

=head1 EXAMPLE USAGE

 perl -I../lib query \
    -verbose \
    -databaseName databaseName \
    -databaseMode DBM \
    Australia@countries, All of Time@years, SAMaker total@cgi-bin scripts

See also L<IncompleteDataCube>.

=cut

#-----------------------------------------------------------------------

use strict;
require 5.002;

use Getopt::Long;
use IO::Pipe;
use IO::File;
use English;
use IncompleteDataCube;

#-----------------------------------------------------------------------

=head1 OPTIONS

=over 4

=item -help

Display a short help message with a reminder of supported
command-line options.

=item -version

Display the version of B<countIt>.

=item -verbose

Enable verbose reporting.

=item -databaseName databaseName

The name of the database, overides the default name 
in L<IncompleteDataCube::Constants>.

=item -databaseMode databaseMode

The mode of the database, overides the default mode
in L<IncompleteDataCube::Constants>.

=back

=cut

#-----------------------------------------------------------------------

use vars qw($VERSION);

my $VERSION       = '1.00';
my $SHOW_VERSION  = 0;
my $VERBOSE       = 0;
my $HELP          = 0;
my $COMMAND_NAME  = 'query';
my $QUERYSTRING = '';

#-----------------------------------------------------------------------
# Parse the command line
#-----------------------------------------------------------------------
&ParseCommandLine();

my $global = new IncompleteDataCube::Globals();
my @u = ();
my @m = ();
my @queryUnitsAbove = ();
my @queryMeasuresBelow = ();

print "Querying for '$QUERYSTRING'.\n" if $VERBOSE;
my $dimension = 0;
foreach (split(',', $QUERYSTRING)) {
  /\s*(.*)\@(.*)\s*/;
  $u[$dimension] = Id::fromStringNoCreate($1);
  die "Exiting: '$1' is not a recognized unit.\n" unless $u[$dimension];
  $m[$dimension] = Id::fromStringNoCreate($2);
  die "Exiting: '$2' is not a recognized measure.\n" unless $m[$dimension];
  $dimension++;
  }

for (my $i = 0; $i < $IncompleteDataCube::Constants::dimensions; $i++) {
  my $temp = $global->{'coarserUnitGraphs'};
  my $g = @$temp[$i];
  $queryUnitsAbove[$i] = $g->reachableSet($u[$i]);
  #print "Units above for $i\n" if $VERBOSE;
  #print $queryUnitsAbove[$i]->image() if $VERBOSE;
  $temp = $global->{'finerMeasureGraphs'};
  $g = @$temp[$i];
  $queryMeasuresBelow[$i] = $g->reachableSet($m[$i]);
  #print "Measures below for $i\n" if $VERBOSE;
  #print $queryMeasuresBelow[$i]->image() if $VERBOSE;
  }

my $querySpec = new CubetteSpecification(\@u, \@m);
my $table = $global->{'filterUnitTable'};
foreach my $keyAsBytes ($table->enumerateKeys) {
  my $key = Id::fromBytes($keyAsBytes);
  my $testSpec = new CubetteSpecification($key, 
        $global->{'filterUnitTable'}, 
        $global->{'filterMeasureTable'});
  my $condition = Cubette::query(
        $testSpec,
        \@queryUnitsAbove,
        \@queryMeasuresBelow);
  if ($condition->fullySatisfied()) {
    my $answer = 
           Cubette::sum(
             $testSpec, 
             $querySpec, 
             $global->{'finerUnitGraphs'}, 
             $global->{'unitToMeasureTables'}, 
             $global->{'countTable'});
        print "And the answer is :\n";
        for (my $k = 0; $k < scalar(@$answer); $k++) {
          my $ref = @$answer[$k];
          print "  " . $ref->image() . "\n";
          }
        exit(0);
        }
      }

#------------------------------------------------------------------------
# ParseCommandLine() - handle command line
#------------------------------------------------------------------------
sub ParseCommandLine {
  my @switches = (
    'databaseMode=s', \$IncompleteDataCube::Constants::databaseMode,
    'databaseName=s', \$IncompleteDataCube::Constants::databaseName,
    'help',           \$HELP,
    'verbose',        \$VERBOSE,
    'version',        \$SHOW_VERSION,
    );

  &GetOptions(@switches) || die "use -help switch to display brief help\n";

  if ($SHOW_VERSION) {
    print "This is $COMMAND_NAME, version $VERSION\n";
    exit 0;
    }

  if ($HELP) {
    print <<HelpEnd;
    $COMMAND_NAME, v$VERSION - parse the log files (actually output
                               of the flex stuff on the log files)

    Usage: $COMMAND_NAME 
                         [-help] |
                         [-version] |
                         [-verbose]
                         [-databaseName databaseName]
                         [-databaseMode GDBM | DBM | BSD]
                         unit\@measure, unit\@measure, ...

        -help            : display this message
        -verbose         : display verbose information as running
        -parser directory : where lieves the parser
        -databaseName name : name of the database
        -databaseMode mode : mode for the database 

HelpEnd
    exit 0;
    }

  $QUERYSTRING = join(' ',@ARGV);

}

