/*
 * @(#)YaltaData.java	0.2 00/08/04
 *
 * Copyright 2000 by Carnegie Mellon, All rights reserved.
 */

package ksdb;
import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;
import javax.swing.*;

import edu.cmu.lti.kantoo.analyzer.*;
import edu.cmu.lti.kantoo.network.*;
import edu.cmu.lti.kantoo.shared.*;


/**
 * Yields output in a style similar to yalta-vista about the analysis/trans
 * of a document
 */
public class YaltaData {

  public static final String[] YaltaScores
    = { "++", "minimal postediting", "incorrect IR", "DM problem",
	"incorrect translation", "bad CTE", "incorrect preposition",
	"word order", "incorrect tense", "truncated output",
	"incorrect morphology", "incorrect voice", "incorrect case",
	"CODA problem", "grammar problem", "other problem",
	"missing translation"};

  public static final String[] KsdbScores
    = { "CORRECT", "MINIMAL", "BAD-IR", "INCORRECT",
	"INCORRECT", "BAD-IR", "LEXICAL",
	"GRAMMAR", "MORPHOLOGY", "TRUNCATION",
	"MORPHOLOGY", "MORPHOLOGY", "MORPHOLOGY",
	"INCORRECT", "GRAMMAR", "INCORRECT",
	"TRUNCATION"};


  /**
   * Returns the language id given the name
   * @param  ksdb         KANTOO Sentence Database object
   * @param  name         Name of language
   * @return              ID of language
   * @throws SQLException if language doesn't exist
   */
  private static int getLanguage(Ksdb ksdb, String name) throws SQLException {
    int id = ksdb.selectInt("id FROM Source_Language WHERE name="
			    + ksdb.quote( name.toLowerCase()));
    if (id == 0)
      throw new SQLException("Language name=" + name
			     + " doesn't exist in KSDB.");
    return id;
  }

  /**
   * Returns the document id given the language and filename
   * @param  ksdb         KANTOO Sentence Database object
   * @param  langauge     Name of language
   * @param  filename     Name of document file
   * @return              ID of document
   * @throws SQLException if document doesn't exist
   */
  private static int getDocument(Ksdb ksdb, String language, String filename)
    throws SQLException {
    int languageID = getLanguage( ksdb, language);
    int id = ksdb.selectInt("id FROM Document WHERE language=" + languageID
			    + " AND filename=" + ksdb.quote( filename));
    if (id == 0)
      throw new SQLException("Document file=" + filename
			     + " doesn't exist in KSDB.");
    return id;
  }

  /**
   * Joins all the arguments after arg (inclusive) in a space-separated string
   * @param args Args sent to program
   * @param arg  First arg of string
   * @return String joining all args. may be NULL if no args provided
   */
  private static String argsRemainder(String[] args, int arg) {
    StringBuffer result = new StringBuffer();
    boolean space = false;
    for (int i = arg; i < args.length; i++) {
      if (space) result.append(' ');
      else space = true;
      if (args[i] != null) result.append( args[i]);
    }
    return result.length() == 0 ? null : new String(result);
  }

  /**
   * Print help info and exit.
   */
  public static void help() {
    System.err.println("Usage: YaltaData");
    System.err.println("\t\tPrint this help.");
    System.err.println("Usage: YaltaData <language> <document>");
    System.err.println("\tPrints out sentences in document");
    System.err.println("Usage: YaltaData <language> <document> <analyzer-version-id>");
    System.err.println("\tAlso prints all IRs of sentences under specified analyzer version");
    System.err.println("Usage: YaltaData <language> <document> <analyzer-id> <generator-id>");
    System.err.println("\tAlso prints out best translation & IR under analyzer/generator versions");
    System.err.println("Usage: YaltaData <language> <document> <analyzer-id> <generator-id> <file>");
    System.err.println("\tAlso imports yalta-vista score file into KSDB");
    System.exit(1);
  }


  /**
   * Returns the quote after i. Ignores quotes after backslashes
   */
  private static int nextQuote( String data, int i) {
    int result = data.indexOf('"', i);
    while (result > 0 && data.charAt(result - 1) == '\\')
      result = data.indexOf('"', result+1);
    return result;
  }

  /**
   * An interpreter interface to the KANTOO Sentence Database
   *
   * @param args commands to send to the KSDB
   */
  public static void main(String[] args) throws IOException, SQLException {
    PropertyManager.getArgs( args);

    Ksdb ksdb = new Ksdb( System.getProperty("user.name"));

    if (args.length < 2) {help(); return;}
    try {
      int analyzer = args.length >= 3 ? Integer.parseInt( args[2]) : 0;
      int generator = args.length >= 4 ? Integer.parseInt( args[3]) : 0;
      RandomAccessFile file = args.length >= 5 ?
	new RandomAccessFile( args[4], "r") : null;

      // We have a single document; print out the sentences assoc with that doc
      int doc = getDocument( ksdb, args[0], args[1]);
      ResultSet rs = ksdb.select("Sentence.text, Sentence.id"
				 + " FROM Context, Sentence"
				 + " WHERE Context.document=" + doc
				 + " AND Context.sentence=Sentence.id"
				 + " ORDER BY Context.position");
      int counter = 0;
      while (SQLConnection.next( rs)) {
	int sentence = SQLConnection.getInt( rs, 2);
	String text = SQLConnection.getString( rs, 1);

	System.out.println();
	System.out.println("(");
	System.out.println(" (:TEXT \"" + text + "\")");
	System.out.println(" (:NUMBER " + counter++ + ")");
	System.out.println(" (:TYPE :SENTENCE)");

	if (analyzer != 0) {
	  if (generator == 0) {
	    System.out.print(" (:INTERLINGUA ");
	    ResultSet irs
	      = ksdb.select("Interlingua.text, Interlingua.id"
			    + " FROM Analysis, Interlingua"
			    + " WHERE Analysis.interlingua=Interlingua.id"
			    + " AND Analysis.version=" + analyzer
			    + " AND Analysis.sentence=" + sentence);
	    boolean first = true;
	    while (SQLConnection.next( irs)) {
	      if (first) first = false;
	      else {System.out.println(); System.out.println();}
	      System.out.print( SQLConnection.getString( irs, 1));
	    }
	    System.out.print(")");

	  } else { // want just the 'best' translation

	    String tl
	      = ksdb.selectString("Target_Language.name FROM Generator_Version, Target_Language"
				  + " WHERE Generator_Version.language=Target_Language.id"
				  + " AND Generator_Version.id=" + generator);
	    // Make a list of all translations, then select the best one
	    ResultSet t1
	      = ksdb.select("text FROM Translation WHERE source=" + sentence);
	    List t2 = new ArrayList();
	    while (SQLConnection.next( t1))
	      t2.add( SQLConnection.getString( t1, 1));
	    String translation = AnalyzerConnection.bestTranslation( t2);
	    if (translation == null) {
	      System.out.println(" (:" + tl + " \"" + text + "\")");
	      System.out.println(" (:STATUS :NO-INTERLINGUA)");
	      System.out.println(" (:TRANS-BY :NONE)");
	    } else {
	      System.out.println(" (:" + tl + " \"" + translation + "\")");
	      System.out.println(" (:STATUS :SUCCESS)");
	      System.out.println(" (:TRANS-BY :AMT)");
	    }
	    System.out.println(" (:COMMENT \"\")");
	    System.out.println(" (:SCORE \"\")");

	    // Get the first IR corresponding to this translation
	    String ir = ksdb.selectString("Interlingua.text"
			    + " FROM Interlingua, Generation, Translation"
			    + " WHERE Interlingua.sentence=" + sentence
			    + " AND Generation.interlingua=Interlingua.id"
			    + " AND Generation.translation=Translation.id"
			    + " AND Translation.text=" + Ksdb.quote( translation));
	    if (translation == null) 
	      System.out.print(" (:INTERLINGUA)");
	    else {
	      System.out.println(" (:INTERLINGUA");
	      System.out.print(" " + ir + ")");
	    }

	    if (file != null) { // must import scores
	      String data = file.readLine();
	      file.readLine(); // blank

	      int q1 = nextQuote( data, -1);
	      int q2 = nextQuote( data, q1+1);
	      int q3 = nextQuote( data, q2+1);
	      int q4 = nextQuote( data, q3+1);
	      int q5 = nextQuote( data, q4+1);
	      int q6 = nextQuote( data, q5+1);
	      String translation2 = data.substring( q1+1, q2);
	      String score = data.substring( q3+1, q4);
	      String comment = data.substring( q5+1, q6);

	      if (translation == null) { // do nothing
	      } else {
		if (! translation.equals( translation2)) {
		  System.err.println("YV & KSDB disagree on best translation for sentence " + (counter-1));
		  System.err.println("\"" + translation2 + "\" vs \"" + translation + "\"");
		}
		  
		int trans = ksdb.selectInt("id FROM Translation WHERE text="
					   + SQLConnection.quote( translation2)
					   + " AND source=" + sentence);
		if (! score.equals("")) {
		  String newScore = null;
		  for (int i = 0; i < YaltaScores.length; i++)
		    if (score.equals( YaltaScores[i])) {
		      newScore = KsdbScores[i];
		      break;
		    }
		  if (newScore != null && trans != 0)
		    ksdb.rateTranslation( trans, newScore);
		}
		if (! comment.equals("") && trans != 0)
		  ksdb.commentTranslation( trans, comment);
	      }
	    }
	  }
	}
	System.out.println(")");
      }
      System.out.println();

    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }

    System.exit(0);
  }
}

