package iitb.cfilt.cpost.ma;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import iitb.cfilt.cpost.ConfigReader;
import iitb.cfilt.cpost.newstemmer.StemmedToken;

public class MorphologicalAnalyzerRuleReader {
	private String stemAnalysisFile ;
	private String suffixAnalysisFile;
	private String stemFlagFile ;
	private String suffixFlagFile ;
	private PrintStream pout=null;
	private HashMap stemHash, suffHash,stemFlagHash,suffFlagHash;
	public MorphologicalAnalyzerRuleReader() {
		stemAnalysisFile=ConfigReader.get("MA.stemAnalysisFile");
		suffixAnalysisFile=ConfigReader.get("MA.suffixAnalysisFile");
		stemFlagFile = ConfigReader.get("MA.stemFlagFile");
		suffixFlagFile = ConfigReader.get("MA.suffixFlagFile");
		createRules();
		createFlagMap();
		
		

	}
	private void createFlagMap(){
		createStemFlagMap();
		createSuffFlagMap();
	}
	private void createStemFlagMap(){
		stemFlagHash = new HashMap();
		
		BufferedReader sBuff=null;
		try {
			sBuff = new BufferedReader(new InputStreamReader(new FileInputStream(stemFlagFile), "UTF8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String line = "" ;
		String paradigm="";
		while (line != null){

			Pattern pEmpty= Pattern.compile("^\\s*$");
			Pattern pIgnore= Pattern.compile("^\\/\\/");
			Matcher mIgnore;
			Matcher mEmpty;
			do{

				try {
					line = sBuff.readLine();
				} catch (IOException e2) {
					System.out.println("Some file error:"+stemFlagFile);
				}	
				if (line!=null)
				{
					line = line.trim();
					mIgnore=pEmpty.matcher(line);
					mEmpty= pIgnore.matcher(line);
				}else break;
			}while (mEmpty.find()||mIgnore.find());
			if (line==null){

			}else{
				if (line.startsWith("#")){
					paradigm = line.substring(1);
				}else{
					Pattern pTab = Pattern.compile("\t");
					Matcher mTab = pTab.matcher(line);
					if (mTab.find()){
						line=mTab.replaceAll(" ");
					}
					Pattern pSpace = Pattern.compile(" ");
					String[] lineComponents = pSpace.split(line);
					if (lineComponents.length==2){
						String stem = lineComponents[0].trim();
						String flag = lineComponents[1].trim();
						//	System.out.println("Paradigm: "+paradigm+"\tstem :"+stem+"\tflag:"+flag);
						if (stemFlagHash.containsKey(stem)){
							HashMap stemPar = (HashMap)stemFlagHash.get(stem);
							if (stemPar.containsKey(paradigm)){
								Vector stemFlag = (Vector) stemPar.get(paradigm);
								stemFlag.add(flag);
								stemPar.put(paradigm,stemFlag);
								stemFlagHash.put(stem,stemPar);
							}else{
								Vector stemFlag = new Vector();
								stemFlag.add(flag);
								stemPar.put(paradigm,stemFlag);
								stemFlagHash.put(stem,stemPar);
							}

						}else{
							HashMap stemPar = new HashMap();
							Vector stemFlag = new Vector();
							stemFlag.add(flag);
							stemPar.put(paradigm,stemFlag);
							stemFlagHash.put(stem,stemPar);
						}
					}
				}
			}
		}
	}
	private void createSuffFlagMap(){
		suffFlagHash = new HashMap();
		
		BufferedReader sBuff=null;
		try {
			sBuff = new BufferedReader(new InputStreamReader(new FileInputStream(suffixFlagFile), "UTF8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String line = "" ;
		String category="";
		while (line != null){

			Pattern pEmpty= Pattern.compile("^\\s*$");
			Pattern pIgnore= Pattern.compile("^\\/\\/");
			Matcher mIgnore;
			Matcher mEmpty;
			do{

				try {
					line = sBuff.readLine();
				} catch (IOException e2) {
					System.out.println("Some file error:"+suffixFlagFile);
				}	
				if (line!=null)
				{
					line = line.trim();
					mIgnore=pEmpty.matcher(line);
					mEmpty= pIgnore.matcher(line);
				}else break;
			}while (mEmpty.find()||mIgnore.find());
			if (line==null){

			}else{
				if (line.startsWith("#")){
					category = line.substring(1);
				}else{
					Pattern pTab = Pattern.compile("\t");
					Matcher mTab = pTab.matcher(line);
					if (mTab.find()){
						line=mTab.replaceAll(" ");
					}
					Pattern pSpace = Pattern.compile(" ");
					String[] lineComponents = pSpace.split(line);
					if (lineComponents.length==2){
						String suff = lineComponents[0].trim();
						String flag = lineComponents[1].trim();
						//		System.out.println("Paradigm: "+category+"\tsuffix :"+suff+"\tflag:"+flag);
						if (suffFlagHash.containsKey(suff)){
							HashMap suffPar = (HashMap)suffFlagHash.get(suff);
							if (suffPar.containsKey(category)){
								Vector suffFlag = (Vector) suffPar.get(category);
								suffFlag.add(flag);
								suffPar.put(category,suffFlag);
								suffFlagHash.put(suff,suffPar);
							}else{
								Vector suffFlag = new Vector();
								suffFlag.add(flag);
								suffPar.put(category,suffFlag);
								suffFlagHash.put(suff,suffPar);
							}

						}else{
							HashMap suffPar = new HashMap();
							Vector suffFlag = new Vector();
							suffFlag.add(flag);
							suffPar.put(category,suffFlag);
							suffFlagHash.put(suff,suffPar);
						}
					}
				}
			}
		}
	}
	private void createRules(){
		try {
			pout = new PrintStream(System.out, true, "UTF8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		stemHash = new HashMap();

		BufferedReader sBuff=null;
		try {
			sBuff = new BufferedReader(new InputStreamReader(new FileInputStream(stemAnalysisFile), "UTF8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String line = "" ;
		while (line != null){

			Pattern pEmpty= Pattern.compile("^\\s*$");
			Pattern pIgnore= Pattern.compile("^\\/\\/");
			Matcher mIgnore;
			Matcher mEmpty;
			do{

				try {
					line = sBuff.readLine();
				} catch (IOException e2) {
					System.out.println("Some file error:"+stemAnalysisFile);
				}	
				if (line!=null)
				{
					line = line.trim();
					mIgnore=pEmpty.matcher(line);
					mEmpty= pIgnore.matcher(line);
				}else break;
			}while (mEmpty.find()||mIgnore.find());
			if (line==null){

			}else{
			//	pout.println(line);
				line=line.replaceAll("\\t", " ");
				line=line.replaceAll("\\s+", " ");
				
				Pattern pComma = Pattern.compile(",");
				Pattern pSpace = Pattern.compile(" ");
				String[] stemLineComponents = pSpace.split(line);
				if (stemLineComponents.length==3){
					String paradigm = stemLineComponents[0].trim();
					String stem = stemLineComponents[1].trim();
					String analysis = stemLineComponents[2].trim();
					Matcher mComma = pComma.matcher(paradigm);
					paradigm = mComma.replaceAll("");
					mComma = pComma.matcher(stem);
					stem = mComma.replaceAll("");
				//	pout.println(stem);
					if (stemHash.containsKey(stem)){
						HashMap stemPar = (HashMap)stemHash.get(stem);
						if (stemPar.containsKey(paradigm)){
							Vector stemAna = (Vector) stemPar.get(paradigm);
							stemAna.add(analysis);
							stemPar.put(paradigm,stemAna);
							stemHash.put(stem,stemPar);
					//		pout.println(stem+","+stemAna);
						}else{
							Vector stemAna = new Vector();
							stemAna.add(analysis);
							stemPar.put(paradigm,stemAna);
							stemHash.put(stem,stemPar);
						//	pout.println(stem+","+stemAna);
						}

					}else{
						HashMap stemPar = new HashMap();
						Vector stemAna = new Vector();
						stemAna.add(analysis);
						stemPar.put(paradigm,stemAna);
						stemHash.put(stem,stemPar);
						//pout.println(stem+","+stemAna);
					}
				}
			}
		}
		/*********************************************************/
		suffHash = new HashMap();
		

		BufferedReader suffBuff=null;
		try {
			suffBuff = new BufferedReader(new InputStreamReader(new FileInputStream(suffixAnalysisFile), "UTF8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String suffline = "" ;
		while (suffline != null){

			Pattern pEmpty= Pattern.compile("^\\s*$");
			Pattern pIgnore= Pattern.compile("^\\/\\/");
			Matcher mIgnore;
			Matcher mEmpty;
			do{

				try {
					suffline = suffBuff.readLine();
				} catch (IOException e2) {
					System.out.println("Some file error:"+suffixAnalysisFile);
				}	
				if (suffline!=null)
				{
					suffline = suffline.trim();
					mIgnore=pEmpty.matcher(suffline);
					mEmpty= pIgnore.matcher(suffline);
				}else break;
			}while (mEmpty.find()||mIgnore.find());
			if (suffline==null){

			}else{
		//		pout.println(suffline);
				Pattern pComma = Pattern.compile(",");
				Pattern pSpace = Pattern.compile(" ");
				String[] suffLineComponents = pComma.split(suffline);
				
				if(suffLineComponents.length != 0)
				{
				String paradigm = suffLineComponents[0].trim();
				String suff = suffLineComponents[1].trim();
				
				
				int i=2;
				String analysis ="";
				while(i<suffLineComponents.length){
					i++;
					Matcher mComma = pComma.matcher(suffLineComponents[i-1]);

					String addOn = mComma.replaceAll("");
					Matcher mSpace = pSpace.matcher(addOn);
					addOn= mSpace.replaceAll("");
					analysis = analysis+","+addOn.trim();
				}


				Matcher mComma = pComma.matcher(analysis);
				analysis = mComma.replaceFirst("");
				//	System.out.println(analysis);
				mComma = pComma.matcher(paradigm);
				paradigm = mComma.replaceAll("");
				mComma = pComma.matcher(suff);
				suff = mComma.replaceAll("");


				if (suffHash.containsKey(suff)){
					HashMap suffPar = (HashMap)suffHash.get(suff);
					if (suffPar.containsKey(paradigm)){
						Vector suffAna = (Vector) suffPar.get(paradigm);
						suffAna.add(analysis);
						suffPar.put(paradigm,suffAna);
						suffHash.put(suff,suffPar);
					}else{
						Vector suffAna = new Vector();
						suffAna.add(analysis);
						suffPar.put(paradigm,suffAna);
						suffHash.put(suff,suffPar);
					}

				}else{
					HashMap suffPar = new HashMap();
					Vector suffAna = new Vector();
					suffAna.add(analysis);
					suffPar.put(paradigm,suffAna);
					suffHash.put(suff,suffPar);
				}
				
			}
				
			}
		}

	}
	
	
	public Vector getSuffixAnalysis(String suffix, String paradigm){
		PrintStream  pout=null;
		try {
			pout = new PrintStream(System.out, true, "UTF8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		suffix = "^"+suffix;
				
		Vector<String> analysis=new Vector<String>();
		Iterator itr = suffHash.keySet().iterator();
		
		
		while(itr.hasNext()){
			String key=(String)itr.next();
			
			if(key.startsWith("^"))
			{
				//suffix = "^" + suffix;
				if (suffix.concat("$").contains(key) && !suffix.concat("$").contains(key.concat("$")))
				{
					HashMap parAna = (HashMap) suffHash.get(key);
					if (parAna.containsKey(paradigm)){
						//pout.println("key:"+key+"suff:"+suffix+"Paradigm : "+paradigm);
	
						
						Vector<String> tempAnalysis=(Vector<String>) parAna.get(paradigm);
					//	analysis.addAll(tempAnalysis);
						Vector<String> newAna;
						/*bigger =new Vector<String>();
						smaller = new Vector<String>();*/
						newAna=new Vector<String>();
						/*if (tempAnalysis.size()>analysis.size()){
							bigger=tempAnalysis;
							smaller=analysis;
						}else{
							smaller=tempAnalysis;
							bigger=analysis;;
						}*/
						//pout.println("Bigger :"+analysis);
						//pout.println("Smaller :"+tempAnalysis);
						for(int i=0;i<analysis.size();i++){
							for(int j=0;j<tempAnalysis.size();j++){
								pout.println("Bigger :"+analysis);
								pout.println("Smaller :"+tempAnalysis);
								//String elematI=bigger.remove(i);
							//	bigger.add(i,elematI.concat(",").concat(smaller.elementAt(j)));
								newAna.add(analysis.elementAt(i).concat(",").concat(tempAnalysis.elementAt(j)));
								//pout.println("new Ana : "+newAna );
							}
						}
						
						if (newAna.isEmpty()){
							newAna=tempAnalysis;
						}
						analysis=newAna;
						//pout.println(analysis);
					}
	
				}
			}
			else
			{
				if (suffix.concat("$").contains(key) && !suffix.concat("$").contains(key.concat("$")))
				{
					HashMap parAna = (HashMap) suffHash.get(key);
					if (parAna.containsKey(paradigm)){
						//pout.println("key:"+key+"suff:"+suffix+"Paradigm : "+paradigm);
	
						
						Vector<String> tempAnalysis=(Vector<String>) parAna.get(paradigm);
					//	analysis.addAll(tempAnalysis);
						Vector<String> newAna;
						/*bigger =new Vector<String>();
						smaller = new Vector<String>();*/
						newAna=new Vector<String>();
						/*if (tempAnalysis.size()>analysis.size()){
							bigger=tempAnalysis;
							smaller=analysis;
						}else{
							smaller=tempAnalysis;
							bigger=analysis;;
						}*/
						//pout.println("Bigger :"+analysis);
						//pout.println("Smaller :"+tempAnalysis);
						for(int i=0;i<analysis.size();i++){
							for(int j=0;j<tempAnalysis.size();j++){
								pout.println("Bigger :"+analysis);
								pout.println("Smaller :"+tempAnalysis);
								//String elematI=bigger.remove(i);
							//	bigger.add(i,elematI.concat(",").concat(smaller.elementAt(j)));
								newAna.add(analysis.elementAt(i).concat(",").concat(tempAnalysis.elementAt(j)));
								//pout.println("new Ana : "+newAna );
							}
						}
						
						if (newAna.isEmpty()){
							newAna=tempAnalysis;
						}
						analysis=newAna;
						//pout.println(analysis);
					}
	
				}
			}

		/*	if (suffHash.containsKey(suffix)){
				HashMap parAna = (HashMap) suffHash.get(suffix);
				if (parAna.containsKey(paradigm)){
					analysis=(Vector) parAna.get(paradigm);
				}
			}*/
		}
		return analysis;

	}
	
	
	
	
	/*
	public Vector getSuffixAnalysis(String suffix, String paradigm){
//		PrintStream  pout=null;
//		try {
//			pout = new PrintStream(System.out, true, "UTF8");
//		} catch (UnsupportedEncodingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}

		Vector analysis=new Vector<String>();
		Iterator itr = suffHash.keySet().iterator();
		while(itr.hasNext()){
			String key=(String)itr.next();
		
			if (suffix.concat("$").contains(key)&&!suffix.concat("$").contains(key.concat("$"))){
				HashMap parAna = (HashMap) suffHash.get(key);
				if (parAna.containsKey(paradigm)){
				//	pout.println("key:"+key+"suff:"+suffix+"Paradigm : "+paradigm);

					
					Vector tempAnalysis=(Vector) parAna.get(paradigm);
				//	analysis.addAll(tempAnalysis);
					Vector<String> bigger,smaller;
					if (tempAnalysis.size()>analysis.size()){
						bigger=tempAnalysis;
						smaller=analysis;
					}else{
						smaller=tempAnalysis;
						bigger=analysis;
					}
					for(int i=0;i<bigger.size();i++){
						for(int j=0;j<smaller.size();j++){
					//		pout.println("Bigger :"+bigger);
						//	pout.println("Smaller :"+smaller);
							String elematI=bigger.remove(i);
							bigger.add(i,elematI.concat(",").concat(smaller.elementAt(j)));
							
						}
					}
					
					analysis=bigger;
			//		pout.println(analysis);
				}

			}

	//		if (suffHash.containsKey(suffix)){
	//			HashMap parAna = (HashMap) suffHash.get(suffix);
	//			if (parAna.containsKey(paradigm)){
	//				analysis=(Vector) parAna.get(paradigm);
	//			}
	//		}
		}
		return analysis;

	}
	*/
	public Vector getStemAnalysis(String root, String paradigm){
		Vector analysis=null;
		if (stemHash.containsKey(root)){
	//		pout.println(true);
			HashMap parAna = (HashMap) stemHash.get(root);
			if (parAna.containsKey(paradigm)){
				analysis=(Vector) parAna.get(paradigm);
			}
		}
		return analysis;
	}
	public Vector<String> getStemFlag(String stem,String category){
//		String[] flag=null;
		Set stemKeys = stemFlagHash.keySet();
		Iterator sKItr = stemKeys.iterator();
		Vector f=null;
		//	System.out.println("Stem: "+stem);
		while(sKItr.hasNext()){
			String hStem=(String)sKItr.next();
			//	System.out.println("Stem: "+stem+"hStem"+hStem);
			if(stem.contains(hStem)){ 
				HashMap parFlag= (HashMap ) stemFlagHash.get(hStem);
				//	System.out.println("hSuffix: "+hStem+"Cate:"+category);
				if (parFlag.containsKey(category)){
					//System.out.println(hStem+category);
					f=(Vector)parFlag.get(category);
				}
			}
		}
		return f;

	}
	public Vector<String> getSuffixFlag(String suffix,String category){
//		String[] flag=null;
		Set suffKeys = suffFlagHash.keySet();
		Iterator sKItr = suffKeys.iterator();
		Vector f =null;
		while(sKItr.hasNext()){
			String hSuffix=(String)sKItr.next();
//			System.out.println(hSuffix);
			if(suffix.contains(hSuffix)){ 
				HashMap parFlag= (HashMap) suffFlagHash.get(hSuffix);
				//			System.out.println("hSuffix: "+hSuffix+"Cate:"+category);
				if (parFlag.containsKey(category)){
					//				System.out.println(hSuffix+category);
					f=(Vector)parFlag.get(category);
					
				}
			}
		}
		return f;

	}

	public MorphologicallyAnalyzedToken analyse(StemmedToken sToken){
		return null;
	}

}
