// file: $isip/util/speech/isip_extract_hypo/isip_extract_hypo.cc
// version: $Id: isip_extract_hypo.cc 10612 2006-08-24 16:00:43Z dom5 $
//
// isip include files
//
#include "isip_extract_hypo.h"

// isip_extract_hypo: utility that extracts hypotheses from the
// transcription database
//
int main(int argc, const char** argv) {

  // setup the command line
  //
  CommandLine cmdl;  
  cmdl.setUsage(
#include "usage_message.text"
                );
  cmdl.setHelp(
#include "help_message.text"
               );

  cmdl.setIdent("$Revision: 10612 $",
		"$Name: $",
		"$Date: 2006-08-24 11:00:43 -0500 (Thu, 24 Aug 2006) $");
  
  // add a command line option for the transcription level ("word : phone")
  //
  String transcription_level;
  cmdl.addOptionParam(transcription_level, OPTION_TRANSCRIPTION_LEVEL, EMPTY);
  
  // add a command line option for the output hypotheses format
  //
  String hypotheses_format;
  cmdl.addOptionParam(hypotheses_format, OPTION_HYPOTHESES_FORMAT,
		      HYPOTHESES_FORMAT_NIST_TRN);      

  // add alignment command line flag
  //
  Boolean alignment = false;
  cmdl.addFlagParam(alignment, OPTION_FLAG_ALIGNMENT);

  // add a command line option for the output hypotheses file
  //
  Filename output_file;
  cmdl.addOptionParam(output_file, OPTION_OUTPUT_FILE, (Filename)EMPTY);
  
  // add a command line option for the identifier list
  //
  Filename identifier_list;
  cmdl.addOptionParam(identifier_list, OPTION_IDENTIFIER_LIST,
		      (Filename)EMPTY);

  // add a command line option for the input exclude-symbols file
  //
  Filename exclude_symbols;
  cmdl.addOptionParam(exclude_symbols, OPTION_EXCLUDE_SYMBOLS,
		      (Filename)EMPTY);
  
  // add a command line option for the debug level
  //
  DebugLevel debug_level;
  cmdl.addOptionParam(debug_level, OPTION_DEBUG_LEVEL, DEBUG_LEVEL_DEFAULT);

  // add a command line option for the log file
  //
  Filename log_file;
  cmdl.addOptionParam(log_file, OPTION_LOG_FILE, (Filename)LOG_FILE_DEFAULT);

  // parse the command line
  //
  if (!cmdl.parse(argc, argv)) {
    cmdl.printUsage();
  };

  // declare the input transcription database
  //
  Filename transdb_file;
  
  // get number of unused arguments (this is the input transcription
  // database)
  //
  long num_arg = (long)cmdl.numArguments();

  // get the database file
  //
  String arg;
  cmdl.getArgument(arg, (long)0);
  transdb_file.concat(arg);
  
  // open the log file
  //
  if (log_file.ne(L"-")) {
    Console::open(log_file);
    Console::setLineWrap(File::NO_WRAP);
  }

  // verify that the user has specified a input transcription database
  //
  if (num_arg < (long)1) {
    cmdl.printUsage();
  };
  
  // branch on no alignment
  //
  if (!alignment) {
    
    // verify that the user has specified the NIST_TRN format
    //
    if (hypotheses_format.ne(HYPOTHESES_FORMAT_NIST_TRN)) {
      cmdl.printUsage();
    };

    // declare the transcription database object
    //
    TranscriptionDatabase trans_db;
    
    // set the debug level
    //
    trans_db.setDebug(debug_level);
    
    // load the transcription database
    //
    if (transdb_file.length() > 0) {
      
      if (debug_level >= Integral::BRIEF) {
	Console::increaseIndention();
	String output;
	output.assign(L"\nloading transcription database: ");
	output.concat(transdb_file);
	Console::put(output);
	Console::decreaseIndention();
      }
            
      // declare the vector of string to store the output hypotheses
      //
      Vector<String> output_hypotheses;
      
      // input identifier list is a sdb object
      //
      Sdb ident_list_sdb;
      if (identifier_list.length() > (long)0) {
	ident_list_sdb.append(identifier_list, true);
      }
      
      // input identifier list is a sdb object
      //
      Sdb exclude_symbols_sdb;
      if (exclude_symbols.length() > (long)0) {
	exclude_symbols_sdb.append(exclude_symbols, true);
      }

      // open the database
      //
      if (!trans_db.open(transdb_file)) {
	return Error::handle(transdb_file.name(), L"error opening transcription database file",
			     Error::ARG, __FILE__, __LINE__);
      }
      
      // get the output hypotheses in NIST_TRN format
      //
      trans_db.getHypothesesNistTrn(ident_list_sdb, exclude_symbols_sdb,
				    transcription_level, output_hypotheses);
      
      // close the database
      //
      trans_db.close();

      // check if the user has specified the output file. if not, then
      // print the output to the console
      //
      if (output_file.eq(EMPTY)) {
	Console::put(L"\nOutput Hypotheses: \n");
	for (long i = 0; i < output_hypotheses.length(); i++) {
	  Console::put(output_hypotheses(i));
	}    
      }
      
      // else, write the output hypotheses to a file
      //
      else {
	File temp_file;
	
	// open the output hypotheses file
	//
	if (!temp_file.open(output_file, File::WRITE_ONLY)) {
	  return Error::handle(output_file.name(), L"no output hypotheses file specified ",			   Error::ARG, __FILE__, __LINE__);
	}
	
	// write the output hypotheses
	//
	for (long i = 0; i < output_hypotheses.length(); i++) {
	  temp_file.put(output_hypotheses(i));
	}
	
	// close the output hypotheses file
	//
	temp_file.close();
      }
    }
  }

  // else output alignments
  //
  else {
    
    // verify that the user has specified the allowable format for
    // output alignnments
    //
    if (hypotheses_format.ne(HYPOTHESES_FORMAT_HYP_ALIGN)) {
      cmdl.printUsage();
    };
    
    // declare the transcription database object
    //
    TranscriptionDatabase trans_db;
    
    // set the debug level
    //
    trans_db.setDebug(debug_level);
    
    // load the transcription database
    //
    if (transdb_file.length() > 0) {
      
      if (debug_level >= Integral::BRIEF) {
	Console::increaseIndention();
	String output;
	output.assign(L"\nloading transcription database: ");
	output.concat(transdb_file);
	Console::put(output);
	Console::decreaseIndention();
      }
      
      if (!trans_db.open(transdb_file)) {
	return Error::handle(transdb_file.name(), L"error loading transcription database",
			     Error::ARG, __FILE__, __LINE__);
      }
      
      // declare the vector of string to store the output alignments
      //
      Vector<String> output_alignments;
      
      // input identifier list is a sdb object
      //
      Sdb ident_list_sdb;
      if (identifier_list.length() > (long)0) {
	ident_list_sdb.append(identifier_list, true);  
      }
      
      // get the output alignments
      //
      trans_db.getAlignmentsHypAlign(ident_list_sdb, transcription_level,
				     output_alignments);
      
      // check if the user has specified the output file. if not, then
      // print the output to the console
      //
      if (output_file.eq(EMPTY)) {
	Console::put(L"\nOutput Alignments: \n");
	for (long i = 0; i < output_alignments.length(); i++) {
	  Console::increaseIndention();
	  Console::put(output_alignments(i));
	  Console::decreaseIndention();
	}
      }
      
      // else, write the output alignments to a file
      //
      else {
	File temp_file;
	
	// open the output alignments file
	//
	if (!temp_file.open(output_file, File::WRITE_ONLY)) {
	  return Error::handle(output_file.name(), L"no output alignment file specified ",			   Error::ARG, __FILE__, __LINE__);
	}
	
	// write the output alignments
	//
	for (long i = 0; i < output_alignments.length(); i++) {
	  temp_file.put(output_alignments(i));
	}
	
	// close the output alignments file
	//
	temp_file.close();
      }
    }
    
    // close the input transcription database
    //
    trans_db.close();
  }

  // exit gracefully
  //
  return Integral::exit();
}
