
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author rouzbeh
 *
 */
public class port_verify {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		
		//constructALETestSetFrom("lkb_25K_result.txt","25k_items.pl");
		//constructALETestSetFrom("lkb_16K_result.txt","16k_items.pl");
		//constructALETestSetFrom("lkb_8K_result.txt","8k_items.pl");
		//constructALETestSetFrom("lkb_4K_result.txt","4k_items.pl");
		
		//doComparison("lkb_16K_result.txt", "lkb_16K_result.txt","16k_plot_dat.txt");
		//doComparison("lkb_4K_result.txt", "ale_4K_result.txt","4k_plot_dat.txt");
		//doComparison("lkb_8K_result.txt", "ale_8K_result.txt","8k_plot_dat.txt");
		
		 
	}//end of main
	
	public static void doComparison(String lkbFileName, String aleFileName,String plotFileName)
	{
		
		List<item_stat> LKBitemStats=null;
		int LKBtotalNumParses=0;
		int LKBtotalNumEdges=0;
		int LKBTotalParseTime = 0;
		int LKBTotalSafeParseTime = 0;
		int LKBTotalFailure = 0;
		
		List<item_stat> ALEitemStats=null;
		int ALEtotalNumParses=0;
		int ALEtotalNumEdges=0;
		int ALETotalParseTime = 0;
		int ALETotalSafeParseTime = 0;
		int ALETotalFailure = 0;
		
		
		try{
			LKBitemStats=readLKBTestResult2(lkbFileName);
			
			ALEitemStats=readALETestResult2(aleFileName);
			
		   }
		   catch (IOException iox) {
				  System.out.println("IOException: "+iox+"\n");
			 }
			
		   
		 for(int i=0; i<LKBitemStats.size();i++){
			 LKBtotalNumParses+=LKBitemStats.get(i).getItmParsNum();
			 LKBtotalNumEdges +=LKBitemStats.get(i).getItmEdgeNum();
			 LKBTotalParseTime += LKBitemStats.get(i).getItmParsTime();
			 if(LKBitemStats.get(i).isEdgeLimitExceeded)
				 LKBTotalFailure ++ ;
			 else
				 LKBTotalSafeParseTime += LKBitemStats.get(i).getItmParsTime();
		 }
		 
		 for(int i=0; i<ALEitemStats.size();i++){
			 ALEtotalNumParses+=ALEitemStats.get(i).getItmParsNum();
			 ALEtotalNumEdges +=ALEitemStats.get(i).getItmEdgeNum();
			 ALETotalParseTime += ALEitemStats.get(i).getItmParsTime();
			 if(ALEitemStats.get(i).isEdgeLimitExceeded)
				 ALETotalFailure ++ ;
			 else
				 ALETotalSafeParseTime += ALEitemStats.get(i).getItmParsTime();
		 }
		 
		 System.out.println("\n---------------LKB--------------------------");
		 System.out.println("Total Numnber of items = "+ LKBitemStats.size());
		 System.out.println("Total Number of Parses = "+LKBtotalNumParses);
		 System.out.println("Total Number of Edges = "+LKBtotalNumEdges);
		 System.out.println("Total Parse Time = "+LKBTotalParseTime+" (msec)");
		 System.out.println("Total Safe Parse Time [Not including those whose edgelimit exceeded] = "+LKBTotalSafeParseTime+" (msec)");
		 System.out.println("Total Edge Limit Exceeded = "+LKBTotalFailure);
		 
		 System.out.println("\n---------------ALE--------------------------");
		 System.out.println("Total Numnber of items = "+ ALEitemStats.size());
		 System.out.println("Total Number of Parses = "+ALEtotalNumParses);
		 System.out.println("Total Number of Edges = "+ALEtotalNumEdges);
		 System.out.println("Total Parse Time = "+ALETotalParseTime+" (msec)");
		 System.out.println("Total Safe Parse Time [Not including those whose edgelimit exceeded/memory problem] = "+ALETotalSafeParseTime+" (msec)");
		 System.out.println("Total Insufficent memory / edgeLimit exceeded incident = "+ALETotalFailure+"\n");
		 
		 
		 try {
			generatePlotData(plotFileName,ALEitemStats,LKBitemStats);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
		 
		 int lkbTime,aleTime=0;
		 int cnt=0;
		 for(int i=0; i<ALEitemStats.size();i++){
			 
			 lkbTime=LKBitemStats.get(i).getItmParsTime();
			 aleTime=ALEitemStats.get(i).getItmParsTime();
			 
			 if( lkbTime < aleTime)
			 {
				 cnt++;
				 System.out.println("@"+i+" LKB Time ="+lkbTime +" < "+aleTime+" =ALE time" );
			 }
		 }
		 System.out.println("Total number of times that LKB parsed the same sentence faster ="+cnt);
		 
	}
	
		
	public static void generatePlotData(String fileName,List<item_stat> ALEStats,List<item_stat> LKBStats) throws IOException {
		
		FileWriter fw = new FileWriter(fileName);
		BufferedWriter bw = new BufferedWriter(fw);
		PrintWriter pw = new PrintWriter(bw);
		pw.println("#Sentence Number\tALE Parse Time\t\tLKB Parse Time");
		for(int i=0; i<ALEStats.size();i++)
		{
			pw.println("\t"+i+"\t\t"+ALEStats.get(i).itmParsTime+ "\t\t\t"+LKBStats.get(i).itmParsTime);
		}	
		pw.close();

	}
	
	
	
	public static void constructALETestSetFrom(String lkbTestresult,String aleTestFile) {
		
		List<item_stat> LKBitemStats=null;
		int LKBtotalNumParses=0;
		int LKBtotalNumEdges=0;
		int LKBtotalParseTime=0;
		int LKBtotalNumberOfItemsWithTime=0;
		
		try{
			 LKBitemStats=readLKBTestResult2(lkbTestresult);
		   }
		   catch (IOException iox) {
				  System.out.println("IOException: "+iox+"\n");
			 }
		   
		for(int i=0; i<LKBitemStats.size()-1;i++){
				 LKBtotalNumParses+=LKBitemStats.get(i).getItmParsNum();
				 LKBtotalNumEdges +=LKBitemStats.get(i).getItmEdgeNum();
				 LKBtotalParseTime +=LKBitemStats.get(i).getItmParsTime();
				 if(LKBitemStats.get(i).isEdgeLimitExceeded)
					 LKBtotalNumberOfItemsWithTime ++;
				 
			 }
		
		System.out.println("\n---------------LKB--------------------------");
		System.out.println("Total Numnber of items: "+ LKBitemStats.size());
		System.out.println("Total Number of Parses ="+LKBtotalNumParses);
		System.out.println("Total Number of Edges ="+LKBtotalNumEdges);  
		System.out.println("Total Parse TIME ="+LKBtotalParseTime);
		System.out.println("Total Number of items with edge limit exhusted ="+LKBtotalNumberOfItemsWithTime);
		System.out.println("\n--------------------------------------------\n");
				
		//try {
		//	writeStatToFile("LKB_DATA.txt",LKBitemStats);
		//} catch (IOException e) {
			// TODO Auto-generated catch block
		//	e.printStackTrace();
		//}
		
		
		try {
			generateALEtestSuite(aleTestFile,LKBitemStats);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
	

public static void writeStatToFile(String fileName,List<item_stat> Stats) throws IOException {
	
	FileWriter fw = new FileWriter(fileName);
	BufferedWriter bw = new BufferedWriter(fw);
	PrintWriter pw = new PrintWriter(bw);
	pw.println("Sentence Number \t Parse Time");
	for(int i=0; i<Stats.size();i++)
	{
		pw.println(""+Stats.get(i).itmNum+" \t\t\t"+Stats.get(i).itmParsTime);
	}	
	pw.close();

}	


public static void generateALEtestSuite(String fileName,List<item_stat> Stats) throws IOException {
	
	FileWriter fw = new FileWriter(fileName);
	BufferedWriter bw = new BufferedWriter(fw);
	PrintWriter pw = new PrintWriter(bw);
	String itm="";
	
	pw.println("% Fuse items with LKB passive edgelimit");
	pw.println("% t/5: t(ItemNumber,isGramatical,ListOfWords,isEdgeLimitExceeded,NumberOfPassiveEdges)");
	for(int i=0; i<Stats.size();i++)
	{
		itm="t("+Stats.get(i).itmNum+","; 
		if(Stats.get(i).isGrameticall)
			itm+="yes";
		else
			itm+="no";
		itm+=",";
		itm+=Stats.get(i).getALEcompatibleSen();
		itm+=",";
		if(Stats.get(i).isEdgeLimitExceeded)
			itm+="yes";
		else
			itm+="no";
		itm+=",";
		itm+=Stats.get(i).getItmEdgeNum();
		itm+=").";
		pw.println(itm);
	}
	
	pw.close();
}

public static List<item_stat> readLKBTestResult2(String strFileName) throws IOException {
		
		FileReader fr = new FileReader(strFileName);
		BufferedReader inBuff = new BufferedReader(fr);
				
		String lineStr;
		StringTokenizer tokenizer;
		
		List<item_stat> itemStats = new ArrayList<item_stat>();
		
		while ((lineStr = inBuff.readLine()) != null)
		{
			if  ( lineStr.length() == 0 )
				continue;
			if (lineStr.charAt(0) == ';')
				continue;
			
			tokenizer = new StringTokenizer(lineStr,",. \t\n\r\f ");
			List<String> item = new ArrayList<String>();
			
			
			while(tokenizer.hasMoreTokens())
			{
				item.add(tokenizer.nextToken());
				
			}
			
			int itemNum,itemParseNum,itemEdgeNum;
			int itemParseTime,itmEdgeLimit;
			boolean isGrametical = true;
			String sen ="";
			
			
			//The first token is item number
			itemNum = Integer.parseInt(item.get(0));
			
			
			if(item.get(1).charAt(0) == '*')
				isGrametical=false;
			
			//sentence is from 1 to Two last
			for(int i=1; i<item.size()-4;i++)
				sen+=" "+item.get(i);
			
			//three to last is the number of parses
			itemParseNum = Integer.parseInt(item.get( item.size()-4 ) );
			
			//two to last token is number of edges
			itemEdgeNum = Integer.parseInt( item.get( item.size()-3 ) );
			
			//One to last is the item parse time in msec
			itemParseTime = Integer.parseInt(item.get( item.size()-2 ) );
			
			//Last token is indicating if edgelimit has been exceeded or not
			// -1 is telling edge limit has been exhusted
			itmEdgeLimit = Integer.parseInt( item.get( item.size()-1 ) );
			
			
			itemStats.add(new item_stat(itemNum,itemParseNum,itemEdgeNum,
										itemParseTime,itmEdgeLimit,
										isGrametical,sen));
			
		}
		return itemStats;
	}


public static List<item_stat> readALETestResult2(String strFileName) throws IOException {
	
	FileReader fr = new FileReader(strFileName);
	BufferedReader inBuff = new BufferedReader(fr);
			
	String lineStr;
	StringTokenizer tokenizer;
	
	List<item_stat> itemStats = new ArrayList<item_stat>();
	
	while ((lineStr = inBuff.readLine()) != null)
	{
		if  ( lineStr.length() == 0 )
			continue;
		if (lineStr.charAt(0) == ';')
			continue;
		
		tokenizer = new StringTokenizer(lineStr,",. \t\n\r\f ");
		List<String> item = new ArrayList<String>();
		
		
		while(tokenizer.hasMoreTokens())
		{
			item.add(tokenizer.nextToken());
			
		}
		
		int itemNum,itemParseNum,itemEdgeNum;
		int itemParseTime,itmEdgeLimit;
		boolean isGrametical = true;
		String sen ="";
		
		
		//The first token is item number
		itemNum = Integer.parseInt(item.get(0));
		
		
		if(item.get(1).charAt(0) == '*')
			isGrametical=false;
		
		//sentence is from 1 to Two last
		for(int i=1; i<item.size()-4;i++)
			sen+=" "+item.get(i);
		
		//three to last is the number of parses
		itemParseNum = Integer.parseInt(item.get( item.size()-4 ) );
		
		//two to last token is number of edges
		itemEdgeNum = Integer.parseInt( item.get( item.size()-3 ) );
		
		//One to last is the item parse time in msec
		itemParseTime = Integer.parseInt(item.get( item.size()-2 ) );
		
		//Last token is indicating if ALE has failed 
		//due to insufficient memory
		String lastTok =item.get( item.size()-1 );
		if(lastTok.equalsIgnoreCase("fail"))
			itmEdgeLimit = -1;
		else
			itmEdgeLimit = 0;
		
		
		itemStats.add(new item_stat(itemNum,itemParseNum,itemEdgeNum,
									itemParseTime,itmEdgeLimit,
									isGrametical,sen));
		
	}
	return itemStats;
}



/**
 * @param strFileName
 * @throws IOException
 */

public static List<item_stat> readLKBTestresult(String strFileName) throws IOException {
	
	FileReader fr = new FileReader(strFileName);
	BufferedReader inBuff = new BufferedReader(fr);
			
	String lineStr;
	StringTokenizer tokenizer;
	
	List<item_stat> itemStats = new ArrayList<item_stat>();
	
	while ((lineStr = inBuff.readLine()) != null)
	{
		if  ( lineStr.length() == 0 )
			continue;
		if (lineStr.charAt(0) == ';')
			continue;
		
		tokenizer = new StringTokenizer(lineStr,",. \t\n\r\f ");
		List<String> item = new ArrayList<String>();
		
		
		while(tokenizer.hasMoreTokens())
		{
			item.add(tokenizer.nextToken());
			
		}
		
		int itemNum,itemParseNum,itemEdgeNum;
		boolean isGrametical = true;
		String sen ="";
		
		
		//The first token is item number
		itemNum = Integer.parseInt(item.get(0));
		
		
		if(item.get(1).charAt(0) == '*')
			isGrametical=false;
		
		//sentence is from 1 to Two last
		for(int i=1; i<item.size()-2;i++)
			sen+=" "+item.get(i);
		
		//One to last is the number of parses
		itemParseNum = Integer.parseInt(item.get( item.size()-2 ) );
		
		//Last token is number of edges
		itemEdgeNum = Integer.parseInt( item.get( item.size()-1 ) );
		
		itemStats.add(new item_stat(itemNum,itemParseNum,itemEdgeNum,isGrametical,sen));
		
	}
	return itemStats;
}

	
	

	
}

class item_stat {

	int itmNum;
	int itmParsNum;
	int itmEdgeNum;
	int itmParsTime; //in msec
	boolean isGrameticall;
	boolean isEdgeLimitExceeded;
	String sen;
	
	
	
	/**
	 * @param itmNum
	 * @param itmParsNum
	 * @param itmEdgeNum
	 * @param isGrameticall
	 * @param sen
	 */
	public item_stat(int itmNum, int itmParsNum, int itmEdgeNum,
			boolean isGrameticall, String sen) {
		super();
		this.itmNum = itmNum;
		this.itmParsNum = itmParsNum;
		this.itmEdgeNum = itmEdgeNum;
		this.isGrameticall = isGrameticall;
		this.sen = sen;
	}
	
	/**
	 * 
	 * @param itmNum
	 * @param itmParsNum
	 * @param itmEdgeNum
	 * @param itmParseTime
	 * @param edgeLimit
	 * @param isGrameticall
	 * @param sen
	 */
	public item_stat(int itmNum, int itmParsNum, int itmEdgeNum,
					 int itmParseTime, int edgeLimit,
					 boolean isGrameticall, String sen) 
	{
		super();
		this.itmNum = itmNum;
		this.itmParsNum = itmParsNum;
		this.itmEdgeNum = itmEdgeNum;
		this.itmParsTime =itmParseTime;
		if(edgeLimit == -1)
			this.isEdgeLimitExceeded = true;
		else
			this.isEdgeLimitExceeded = false;
		
		this.isGrameticall = isGrameticall;
		this.sen = sen;
	}
	
	
	/**
	 * @param itmNum
	 * @param itmParsNum
	 * @param itmEdgeNum
	 */
	public item_stat(int itmNum, int itmParsNum, int itmEdgeNum) {
		super();
		this.itmNum = itmNum;
		this.itmParsNum = itmParsNum;
		this.itmEdgeNum = itmEdgeNum;
	}
	
	public int getItmNum() {
		return itmNum;
	}
	public void setItmNum(int itmNum) {
		this.itmNum = itmNum;
	}
	public int getItmParsNum() {
		return itmParsNum;
	}
	public void setItmParsNum(int itmParsNum) {
		this.itmParsNum = itmParsNum;
	}
	public int getItmEdgeNum() {
		return itmEdgeNum;
	}
	public void setItmEdgeNum(int itmEdgeNum) {
		this.itmEdgeNum = itmEdgeNum;
	}
	public int getItmParsTime() {
		return itmParsTime;
	}
	public void setItmParsTime(int itmParsTime) {
		this.itmParsTime = itmParsTime;
	}
	public boolean isGrameticall() {
		return isGrameticall;
	}
	public void setGrameticall(boolean isGrameticall) {
		this.isGrameticall = isGrameticall;
	}
	
	public int getSenLength() {
		return sen.length();
	}
	
	public String getSen() {
		return sen;
	}
	public void setSen(String sen) {
		this.sen = sen;
	}
	
	public String getALEcompatibleSen() {
		String aleSen="[";
		StringTokenizer tokenizer;
			
		tokenizer = new StringTokenizer(this.sen,"!*?,. \t\n\r\f ");
		while(tokenizer.hasMoreTokens())
		{
			aleSen+=tokenizer.nextToken().toLowerCase().replace("-", "_").replace(",", "_").replace("'", "_");
			if(tokenizer.hasMoreTokens())
				aleSen+=",";
		}
		aleSen+="]";
		return aleSen;
	}
	
		
	public String toString()
	{
		return ""+this.itmNum+this.sen+" "+this.itmParsNum+" "+this.itmEdgeNum+"\n";
	}
	
	public String toStringFull(){
		String ret ="";
		ret+=""+this.itmNum+this.sen+" "+this.itmParsNum+" "+this.itmEdgeNum+" "+this.itmParsTime;
		
		if(this.isEdgeLimitExceeded)
			ret+=" *edgelimit_exceeded*";
		else
			ret+=" *OK*";
		
		ret+=" \n";
		return ret;
		
	}
	
}
