// file: $isip/util/speech/isip_sr/isip_sr.cc
// version: $Id: isip_recognize.cc 10620 2006-08-24 16:04:15Z dom5 $
//
// isip include files
//
#include "isip_recognize.h"
#include "HierarchicalSearch.h"

// isip_decoder: core part of SR system, outputs transcribed speech
//
// it will be used for
//    viterbi alignment
//    lattice rescoring (n-gram rescoring or acoustic model rescoring)
//    ngram decoding
//    lattice generation (from a lattice or from an n-gram LM)
//    lattice error rate calculation
//
int main(int argc, const char** argv) {

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

  cmdl.setIdent("$Revision: 10620 $",
		"$Name: $",
		"$Date: 2006-08-24 11:04:15 -0500 (Thu, 24 Aug 2006) $");
  
  // add a command line option for the parameters file
  //
  Filename params_file;
  cmdl.addOptionParam(params_file, OPTION_PARAMS_FILE, (Filename)EMPTY);

  // add a command line option for the accumulator file
  //
  Filename accum_file;
  cmdl.addOptionParam(accum_file, OPTION_ACCUMULATOR_FILE, (Filename)EMPTY);

  // add a command line option for the accumulator list
  //
  Filename accum_list;
  cmdl.addOptionParam(accum_list, OPTION_ACCUMULATOR_LIST, (Filename)EMPTY);
  
  // add a command line option for the mode of operation (Cluster or
  // Single(Def))
  String mode;
  cmdl.addOptionParam(mode,OPTION_MODE_SWITCH, EMPTY);
  
  // add a command line option for the output mode
  //
  String output_mode;
  cmdl.addOptionParam(output_mode, OPTION_OUTPUT_MODE, EMPTY);

  // add a command line option for the function mode
  //
  String function_mode;
  cmdl.addOptionParam(function_mode, OPTION_FUNCTION_MODE, EMPTY);  
  
  // add a command line option for the output format
  //
  String output_format;
  cmdl.addOptionParam(output_format, OPTION_OUTPUT_FORMAT, (Filename)EMPTY);

  // add a command line option for the output file
  //
  Filename output_file;
  cmdl.addOptionParam(output_file, OPTION_OUTPUT_FILE, (Filename)EMPTY);
  
  // add a command line option for the output list
  //
  Filename output_list;
  cmdl.addOptionParam(output_list, OPTION_OUTPUT_LIST, (Filename)EMPTY);

  // add a command line option for the language model file
  //
  Filename lm_file;
  cmdl.addOptionParam(lm_file, OPTION_LANGUAGE_MODEL_FILE, (Filename)EMPTY);

  // add a command line option for the statistical model pool file
  //
  Filename smp_file;
  cmdl.addOptionParam(smp_file, OPTION_STATISTICAL_MODEL_POOL_FILE,
		      (Filename)EMPTY);

  // add a command line option for the language model output file
  //
  Filename lm_output_file;
  cmdl.addOptionParam(lm_output_file, OPTION_LANGUAGE_MODEL_OUTPUT_FILE,
		      (Filename)EMPTY);

  // add a command line option for the statistical model pool output file
  //
  Filename smp_output_file;
  cmdl.addOptionParam(smp_output_file,
		      OPTION_STATISTICAL_MODEL_POOL_OUTPUT_FILE,
		      (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 verbosity level
  //
  DebugLevel verbosity;
  cmdl.addOptionParam(verbosity, OPTION_VERBOSITY_LEVEL,
		      VERBOSITY_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);
  
  // add verify command line option for output levels
  //
  String output_level;
  cmdl.addOptionParam(output_level, OPTION_OUTPUT_LEVEL, EMPTY);
  
  // add verify command line option for update levels
  //
  String update_level;
  cmdl.addOptionParam(update_level, OPTION_UPDATE_LEVEL, EMPTY);
  
  // add a command line option for the decision tree file
  //
  Filename dt_file;
  cmdl.addOptionParam(dt_file, OPTION_DECISION_TREE_FILE, (Filename)EMPTY);

  // add a command line option for the question and answer file
  //
  Filename qes_ans_file;
  cmdl.addOptionParam(qes_ans_file, OPTION_QUESTION_ANSWER_FILE, (Filename)EMPTY);  

  // add a command line option for merge thresholds
  //
  String merge_threshold;
  cmdl.addOptionParam(merge_threshold, OPTION_MERGE_THRESHOLD, EMPTY);
  
  // add a command line option for split thresholds
  //
  String split_threshold;
  cmdl.addOptionParam(split_threshold, OPTION_SPLIT_THRESHOLD, EMPTY);
  
  // add verify command line option for occupancy threshold
  //
  String occ_threshold;
  cmdl.addOptionParam(occ_threshold, OPTION_OCC_THRESHOLD, EMPTY);

  // add streaming input command line flag
  //
  Boolean stream;
  cmdl.addFlagParam(stream, OPTION_FLAG_STREAM);

  // add verify command line flag
  //
  Boolean verify;
  cmdl.addFlagParam(verify, OPTION_FLAG_VERIFY);
  
  // add a command line option for output identifier for hypotheses
  //
  Filename output_base_name;
  cmdl.addOptionParam(output_base_name, OPTION_OUTPUT_BASE_NAME,(Filename) EMPTY);

  // add a command line option for the accumulator path
  // this option will store all the accumulator files in the specified
  // directory
  //
  Filename accumulator_path;
  cmdl.addOptionParam(accumulator_path, OPTION_ACCUMULATOR_PATH,(Filename) EMPTY);

  // add a command line option for the accumulator file basename
  //
  String accumulator_name;
  cmdl.addOptionParam(accumulator_name, OPTION_ACCUMULATOR_NAME, EMPTY);
  
  // parse the command line
  //
  if (!cmdl.parse(argc, argv)) {
    cmdl.printUsage();
  };

  // open the log file
  //
  if (log_file.ne(L"-")) {
    Console::open(log_file);
    Console::setLineWrap(File::NO_WRAP);
  }

  // print the command line
  //
  if (verbosity >= Integral::BRIEF) {
    cmdl.printCommandLine();
    cmdl.printVersion();
    //HierarchicalSearch::setDebug(Integral::BRIEF);
  }

  // check the param file argument
  //
  if(params_file.eq((Filename)EMPTY)) {
    cmdl.printUsage();
  };

  // set up the speech recognizer
  //
  SpeechRecognizer sr;

  // read parameters from the parameter file
  //
  sr.setParam(params_file);

  // set parameters from the command line
  //
  sr.setStream(stream);
  sr.setVerify(verify);
  sr.setDebug(debug_level);
  sr.setVerbosity(verbosity);
  sr.setAccumulatorFile(accum_file);
  sr.setAccumulatorList(accum_list);
  sr.setAccumulatorPath(accumulator_path);
  sr.setAccumulatorName(accumulator_name);
  sr.setOutputMode(output_mode);
  sr.setOutputFormat(output_format);
  sr.setOutputFile(output_file);
  sr.setOutputList(output_list);
  sr.setFunctionMode(function_mode);
  sr.setLanguageModelFile(lm_file);
  sr.setLanguageModelUpdateFile(lm_output_file);
  sr.setStatisticalModelPoolFile(smp_file);
  sr.setStatisticalModelPoolUpdateFile(smp_output_file);
  sr.setOutputLevelString(output_level);
  sr.setUpdateLevelString(update_level);  
  
  // decision tree parameters
  //
  sr.setDecisionTreeFile(dt_file);
  sr.setQuesAnswerFile(qes_ans_file);
  sr.setSplitThreshold(split_threshold);
  sr.setMergeThreshold(merge_threshold);
  sr.setNumOccThreshold(occ_threshold);

  // if streaming input, there must either be list or base name provided
  //
  if (stream) {

    // if no list file was provided, sdb is empty.
    // in which case, we must have a base name
    //
    if (!sdb.gotoFirst()) {

      // adding base name if users specified
      //
      if (output_base_name.length() > 0) {
	sdb.append(output_base_name);
      }

      // if no base name or list file, error out.
      //
      else {
	cmdl.printUsage();
      }
    }
    
  }
  
  // run the speech recognizer
  //
  sr.run(sdb);
  
  // close the log file
  //
  if (log_file.ne(L"-")) {
    Console::close();
  }

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