package emn.fr.ascola.extractor;

import java.util.HashMap;
import java.util.Vector;

import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;

/**
 * Class to store per type name the set of required services
 * @author jroyer
 *
 */
public class Provided extends HashMap<String, Vector<IMethod>>{
	private static final long serialVersionUID = 1L;

	public String toString() {
		String result = "";
		for (String typ : this.keySet()) {
			result += typ + " :::";
			for(IMethod im : this.get(typ)) {
					result += " " + this.computeSignature(im);
			}
			result += "\n";
		}
		return result;
	}
	
	/**
	 * Compute the provided interface of a type.
	 * @param key
	 * @return an array of String signatures.
	 */
	public Vector<String> getProvided(String key) {
		Vector<IMethod> meths = this.get(key);
		Vector<String> result = new Vector<String>();
		for(IMethod im : meths) {
			result.add(this.computeSignature(im));
		}
		return result;
	}
	
	/**
	 * Compute a readable signature without fully qualified names.
	 * @param im
	 * @return
	 * TODO pas correct for constructor
	 */
	public String computeSignature(IMethod im) {
		try {
			// Good version
			String result = Signature.toString(im.getSignature(), im.getElementName(), 
					im.getParameterNames(), true, true);
			// return result;
			// other style not nice
			/*
			String rtype = im.getReturnType();
			String ptypes = "";
			for (String st : im.getParameterNames()) {
				ptypes += st + " ";
			}
			// communication creation
			return im.getElementName() + "(" + ptypes + ") -> " + rtype; */
			int ind = result.indexOf(" ");
			String rettype = result.substring(0, ind);
			if (im.isConstructor()) {
				// for constructor it is the declaring type
				rettype = im.getElementName();
			}
			return result.substring(ind) + "-> " + rettype;	
		} catch (JavaModelException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * Check if the req method has a corresponding 
	 * provided method.
	 * TODO
	 * @param req
	 */
	public void exists(String trec, IMethodBinding req) {
		Vector<IMethod> im = this.get(trec);
		for (IMethod m : im) {
			try {
				Signature.toString(m.getSignature(), m.getElementName(), m.getParameterNames(), true, true);
				//System.out.println("                 " + Signature.toString(m.getSignature(), m.getElementName(), m.getParameterNames(), true, true));
				//System.out.println("         resolue ? " + m.isResolved());
			} catch (JavaModelException e) {
				e.printStackTrace();
			}
		}
	}

}
