#! /usr/bin/env perl 

my $MLLIBS; 
my $VERSION; 
BEGIN {
    $VERSION = "0.1";
    
    # REPLACE THE VALUE OF THIS ASSIGNMENT SO THAT 
    #  $ROOT POINTS TO THE PATH OF PHRECO
    $ROOT = "$ENV{HOME}/local/phreco";
}
use lib "$ROOT/src";
use lib "$ROOT/src/ML";


use strict;

use PHRECO::config; 
use PHRECO::chunkconfig; 
use PHRECO::frchunker;

use PHRECO::sentence;


use AppConfig qw(:argcount);

my $script = $0;
my $help = << "end_of_help;";
fr-chunker : recognizes (non-overlapped, non-embedded) phrases in a sentence 
usage: fr-chunker [options] <mode> <mode parameters>

Modes:   
    -gen     [<dataset>]           Word Inputs generation
    -train   <dataset>             Train score functions
    -retrain <dataset>
    -label   [<dataset>]           Label dataset (Default)

General Options:
    -v       <int>                Verbosity level. Default: 0.

end_of_help;

$help .= PHRECO::chunkconfig::config_help() . "\n";



my $speccfg = AppConfig->new({ CASE=>1 }, "model_dir=s");
my $config  = AppConfig->new( { CASE=>1, GLOBAL => { ARGCOUNT => ARGCOUNT_ONE } });


PHRECO::config::config_definition($config);
PHRECO::chunkconfig::config_definition($config);

$config->define("verbose", { ALIAS => "v", DEFAULT => 0 });


if (!@ARGV) {
    print $help; 
    exit; 
}

########################################
## Options Processing

##  first the config file
#$speccfg->getopt("pass_through");
#if (defined($speccfg->spec)) {
#    $config->file($speccfg->spec);
#}
#  then the command-line arguments
#$config->getopt();

$speccfg->getopt("pass_through");
if (defined($speccfg->model_dir) and -f $speccfg->model_dir."/spec") {
    $config->set("model_dir", $speccfg->model_dir);
    $config->file($speccfg->model_dir."/spec");
}
#  then the command-line arguments
$config->getopt();




my $verbose = $config->get("verbose");
PHRECO::frchunker::set_verbosity($verbose);


## Phrase Types 
my @phrase_types = @{$config->get("K")};
if (@phrase_types) {
    print STDERR "Considering types: ", join(" ", @phrase_types), "\n" if $verbose;
    PHRECO::phrase_set::set_phrase_types(@phrase_types);
}


###

# Mandatory Arguments 
my $mode = undef

# arguments
my $dsfile = undef;


if ($config->get("gen")) {
    $mode = "g";
    $dsfile = (@ARGV) ? shift @ARGV : undef;
}
if ($config->get("train")) {
    defined($mode) and die "$script : two modes specified (", $mode, " and t)!\n"; 
    $mode = "t";
    if (defined($config->get("training_file"))) {
	$dsfile = $config->get("training_file"); 
    }
    else {
	$dsfile = shift @ARGV or die "$script: unspecified dataset!\n$help";
    }
}
if ($config->get("retrain")) {
    defined($mode) and die "$script : two modes specified (", $mode, " and r)!\n"; 
    $mode = "r";
    $dsfile = shift @ARGV or die "$script: unspecified dataset!\n";
}
if (!defined($mode)) {
    $mode = "l";
    $dsfile = (@ARGV) ? shift @ARGV : undef;    
}



## Input Specification
my $input_spec = undef;
if ($config->get("input")) {
    $input_spec = $config->get("input"); 
}
elsif ($mode eq "l") {
    $input_spec = "wp";
}
else {
    $input_spec = "wpc";
}
PHRECO::sentence::set_input_spec($input_spec);

my $epochs = $config->get("epochs");


#----------------------------------------------------------------------
#  M A I N   P R O G R A M 
#

my $chunker = PHRECO::frchunker->new($mode, $config);

if ($mode eq "t" or $mode eq "r") {
    $chunker->train($dsfile, $epochs);
    exit;
}

## Labelling, Generation


## Open DataSet
my $dsfh;
if (defined($dsfile)) {
    if ($dsfile =~ /\.gz$/) {
	open DS, "gunzip -c $dsfile |" or die "$script: error opening dataset $dsfile: $!\n";    
    }
    else {
	open DS, $dsfile or die "$script: error opening dataset $dsfile: $!\n";    
    }
    $dsfh = \*DS;
}
else {
    $dsfh = \*STDIN;
}

my $nsentence = 0;
my $x = PHRECO::sentence->read_from_stream($nsentence, $dsfh);
while ($x) {
    
    if ($verbose) {
	print "*/", ' Sentence #', $nsentence, " : \n  ";
	map { print $_->id, ":", $_->form; ($_->chunk_tag ne "O") and print ":", $_->chunk_tag; print " "; } $x->words;
	print "\n";
	print "   -> Chunking: ", $x->phraseS->to_string, "\n";
    }

    my $y;
    if ($mode eq "l") {
	$y = $chunker->process_sentence($x);
	if ($verbose) {
	    print "   -> Result: ", $y->to_string, "\n\n";	    
	}	
    }
    elsif ($mode eq "g") {
	$chunker->generate_word_inputs($x);
    }

    
    ## Write Chunks 
    if ($mode eq "l") {
	my @out = $y->to_IOB2_tagging($x->length); 
	my $w;
	foreach $w ( $x->words ) {
#	    print join (" ", $w->form, $w->pos, $w->chunk_tag, $out[$w->id]), "\n";
	    print join (" ", $w->fields, $out[$w->id]), "\n";
	}
	print "\n";
    }
    
    $nsentence++;
    $x = PHRECO::sentence->read_from_stream($nsentence, $dsfh);
}

