/*
 **********************************************************************
 * Copyright (c) 2006-2012, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Created on 2006-7-24 ?
 * Moved from Java 1.4 to 1.5? API by srl 2009-01-16
 */
package com.ibm.icu.dev.tools.docs;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


/**
 A utility to report the status change between two ICU releases

To use the utility
1. Generate the XML files
    (put the two ICU releases on your machine ^_^ )
    (generate 'Doxygen' file on Windows platform with Cygwin's help)
    Edit the generated 'Doxygen' file under ICU4C source directory
    a) GENERATE_XML           = YES
    b) Sync the ALIASES definiation
       (For example, copy the ALIASES defination from ICU 3.6
       Doxygen file to ICU 3.4 Doxygen file.)
    c) gerenate the XML files
2. Build the tool
    Download Apache Xerces Java Parser
    Build this file with the library
3. Edit the api-report-config.xml file & Change the file according your real configuration
4. Run the tool to generate the report.

 * @author Raymond Yang
 */
public class StableAPI {

    private static final String DOC_FOLDER = "docFolder";
	private static final String INDEX_XML = "index.xml";
	private static final String ICU_SPACE_PREFIX = "ICU ";
	private static final String INITIALIZER_XPATH = "initializer";
	private static final String NAME_XPATH = "name";
	private static final String UVERSIONA = "uvernum_8h.xml";
	private static final String UVERSIONB = "uversion_8h.xml";
    private static final String U_ICU_VERSION = "U_ICU_VERSION";
    /* ICU 4.4+ */
	private static final String ICU_VERSION_XPATHA = "/doxygen/compounddef[@id='uvernum_8h'][@kind='file']/sectiondef[@kind='define']";
	/* ICU <4.4 */
	private static final String ICU_VERSION_XPATHB = "/doxygen/compounddef[@id='uversion_8h'][@kind='file']/sectiondef[@kind='define']";
    private static String ICU_VERSION_XPATH = ICU_VERSION_XPATHA;

	private String leftVer;
    private File leftDir = null;
//    private String leftStatus;
    private String leftMilestone = "";
    
    private String rightVer;
    private File rightDir = null;
//    private String rightStatus;
    private String rightMilestone = "";

    private InputStream dumpCppXsltStream = null; 
	private InputStream dumpCXsltStream = null;
	private InputStream reportXslStream = null;
	private static final String CXSLT = "dumpAllCFunc.xslt";
	private static final String CPPXSLT = "dumpAllCppFunc.xslt"; 
	private static final String RPTXSLT = "genReport.xslt";

    private File dumpCppXslt;
    private File dumpCXslt;
    private File reportXsl;
    private File resultFile;
    

    static Map<String,Set<String>> simplifications = new TreeMap<String,Set<String>>();
    
    static void addSimplification(String prototype0, String prototype) {
        Set<String> s = simplifications.get(prototype);
        if(s==null) {
            s = new TreeSet<String>();
            simplifications.put(prototype, s);
        }
        s.add(prototype0);
    }

    static Set<String> getChangedSimplifications() {
        Set<String> output = new TreeSet<String>();
        for(Map.Entry<String,Set<String>> e : simplifications.entrySet()) {
            if(e.getValue().size()>1) {
                output.add(e.getKey());
            }
        }
        return output;
    }

    
    final private static String nul = "None"; 

    public static void main(String[] args) throws TransformerException, ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        
        StableAPI t = new StableAPI();
        t.run(args); 
    }
    
    private void run(String[] args) throws XPathExpressionException, TransformerException, ParserConfigurationException, SAXException, IOException {
        this.parseArgs(args);
        Set<JoinedFunction> full = new TreeSet<JoinedFunction>();

        System.err.println("Reading C++...");
        Set<JoinedFunction> setCpp = this.getFullList(dumpCppXsltStream, CPPXSLT);
        full.addAll(setCpp);
        System.out.println("read "+setCpp.size() +" C++.  Reading C:");
        
        Set<JoinedFunction> setC = this.getFullList(dumpCXsltStream, CXSLT);
        full.addAll(setC);

        System.out.println("read "+setC.size() +" C. Setting node:");
        
        Node fullList = this.setToNode(full);
//        t.dumpNode(fullList,"");
        
        System.out.println("Node set. Reporting:");
        
        this.reportSelectedFun(fullList);
        System.out.println("Done. Please check " + this.resultFile);

        Set<String> changedSimp = getChangedSimplifications();
        if(!changedSimp.isEmpty()) {
            System.out.println("--- changed simplifications ---");
            for(String k : changedSimp) {
                System.out.println(k);
                for(String s : simplifications.get(k)) {
                    System.out.println("\t"+s);
                }
            }
        }
    }


    private void parseArgs(String[] args){
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            if (arg == null || arg.length() == 0) {
                continue;
            }
            if (arg.equals("--help") ) {
                printUsage();
            } else if (arg.equals("--oldver") ) {
                leftVer = args[++i];
            } else if (arg.equals("--olddir") ) {
                leftDir = new File(args[++i]);
            } else if (arg.equals("--newver")) {
                rightVer = args[++i];
            } else if (arg.equals("--newdir")) {
                rightDir = new File(args[++i]);
            } else if (arg.equals("--cxslt") ) {
                dumpCXslt = new File(args[++i]);
            } else if (arg.equals("--cppxslt") ) {
                dumpCppXslt = new File(args[++i]);
            } else if (arg.equals("--reportxslt") ) {
                reportXsl = new File(args[++i]);
            } else if (arg.equals("--resultfile")) {
                resultFile = new File(args[++i]);
            } else {
                System.out.println("Unknown option: "+arg);
               printUsage();
            } 
        }

        dumpCppXsltStream = loadStream(CPPXSLT, "--cppxslt", dumpCppXslt);
        dumpCXsltStream= loadStream(CXSLT, "--cxslt", dumpCXslt);
        reportXslStream= loadStream(RPTXSLT, "--reportxslt", reportXsl);

        leftVer = trimICU(setVer(leftVer, "old", leftDir));
        rightVer = trimICU(setVer(rightVer, "new", rightDir));
    }


    @SuppressWarnings("resource")
	private InputStream loadStream(String name, String argName, File argFile) {
    	InputStream stream = null;
    	if(argFile != null) {
    		try {
	    		stream = new FileInputStream(argFile);
	    	} catch (IOException ioe) {
	    		throw new RuntimeException("Error: Could not load " + argName +" " + argFile.getPath() + " - " + ioe.toString(), ioe);
	    	}
    	} else {    	
        	stream = StableAPI.class.getResourceAsStream(name);
        	if(stream == null) {
        		throw new InternalError("No resource found for " + StableAPI.class.getPackage().getName()+"/"+ name + " -   use " + argName);
        	} else {
        		System.out.println("Loaded resource " + name);
        	}
        }
        return stream;
	}

    private static Set<String> warnSet = new TreeSet<String>();
    
    private static void warn(String what) {
        if(!warnSet.contains(what)) {
               System.out.println("Warning: "+what);
               if(warnSet.isEmpty()) {
                      System.out.println(" (These warnings are only printed one time each.)");
               }
               warnSet.add(what);
        }
    } 
    
    private static boolean didWarnSuperTrim = false;
    
    private static String trimICU(String ver) {
        final String ICU_ = ICU_SPACE_PREFIX;
        final String ICU = "ICU";
        if(ver != null) { // trim everything before the 'ICU...'
            ver = ver.trim();
            int icuidx = ver.lastIndexOf(ICU_);
            int icuidx1 = ver.lastIndexOf(ICU);
            if(icuidx>=0) {
                warn("Trimming text before 'ICU': " + ver.substring(0,icuidx+ICU_.length()));
                ver = ver.substring(icuidx+ICU_.length()).trim();
            } else if(icuidx1>=0) {
                warn("Trimming text before 'ICU ': " + ver.substring(0,icuidx1+ICU.length()));
                ver = ver.substring(icuidx1+ICU.length()).trim();
            }
            
            // always trim anything after a version #
            {
                int n;
                for(n=ver.length()-1;n>0 && ((ver.charAt(n)=='.') || Character.isDigit(ver.charAt(n))) ;n--)
                    ;
                if(n>0) {
                    warn("Trimming extraneous text after version: '" + ver.substring(n+1,ver.length()) + "'");
                    ver = ver.substring(n+1).trim();
                    if(!didWarnSuperTrim) {
                	didWarnSuperTrim = true;
                	warn("Please ONLY use:  '@whatever ICU X.Y.Z'");
                    }
                }
            }
        } 
        return ver;
    }
    
    private String setVer(String prevVer, String whichVer, File dir) {
	    String UVERSION = UVERSIONA;
    	if(dir==null) {
    		System.out.println("--"+whichVer+"dir not set.");
    		printUsage(); /* exits */
    	} else if(!dir.exists()||!dir.isDirectory()) {
    		System.out.println("--"+whichVer+"dir="+dir.getName()+" does not exist or is not a directory.");
    		printUsage(); /* exits */
    	}
        String result = null;
        // looking for: <name>U_ICU_VERSION</name> in uversion_8h.xml:        <initializer>&quot;3.8.1&quot;</initializer>
        try {
            File verFile = new File(dir, UVERSION);
		    if(!verFile.exists()) {
				UVERSION=UVERSIONB;
				ICU_VERSION_XPATH=ICU_VERSION_XPATHB;
				verFile = new File(dir, UVERSION);
		    } else {
				ICU_VERSION_XPATH=ICU_VERSION_XPATHA;
		    }
            Document doc = getDocument(verFile);
            DOMSource uvernum_h = new DOMSource(doc);
            XPath xpath = XPathFactory.newInstance().newXPath();

            Node defines = (Node)xpath.evaluate(ICU_VERSION_XPATH, uvernum_h.getNode(), XPathConstants.NODE);

	    if(defines==null) {
	    	System.err.println("can't load from "+verFile.getName()+":"+ICU_VERSION_XPATH);
	    }

            NodeList nList = defines.getChildNodes();
            for (int i = 0; result==null&& (i < nList.getLength()); i++) {
                Node ln = nList.item(i);
                if(!"memberdef".equals(ln.getNodeName())) {
                    continue;
                }
                Node name = (Node)xpath.evaluate(NAME_XPATH, ln, XPathConstants.NODE);
                if(name==null) continue;
                
               // System.err.println("Gotta node: " + name);
                
                Node nameVal = name.getFirstChild();
                if(nameVal==null) nameVal = name;
                
                String nameStr = nameVal.getNodeValue();
                if(nameStr==null) continue;

               // System.err.println("Gotta name: " + nameStr);
                
                if(nameStr.trim().equals(U_ICU_VERSION)) {
                    Node initializer = (Node)xpath.evaluate(INITIALIZER_XPATH, ln, XPathConstants.NODE);
                    if(initializer==null) System.err.println("initializer with no value");
                    Node initVal = initializer.getFirstChild();
//                    if(initVal==null) initVal = initializer;
                    String initStr = initVal.getNodeValue().trim().replaceAll("\"","");
                    result = ICU_SPACE_PREFIX+initStr;
                    System.err.println("Detected "+whichVer + " version: " + result);

                    String milestoneOf = "";
                    
                    // TODO:  #1 use UVersionInfo. (this tool doesn't depend on ICU4J yet) 
                    //        #2 move this to a utility function: strip/"explain" an ICU version #.
                    if(result.startsWith("ICU ")) {
                        String vers[] = result.substring(4).split("\\.");
                        int maj = Integer.parseInt(vers[0]);
                        int min = vers.length>1?Integer.parseInt(vers[1]):0;
                        int micr = vers.length>2?Integer.parseInt(vers[2]):0;
                        int patch = vers.length>3?Integer.parseInt(vers[3]):0;
                        
                        if(maj >= 49) {
                            // new scheme: 49 and following. 
                            String truncVersion = "ICU " +maj;
                            if(min == 0) {
                                milestoneOf = " (m"+micr+")";
                                System.err.println("    .. " + milestoneOf + " is a milestone towards " + truncVersion);
                            } else if(min == 1) {
                                // Don't denote as milestone
                                result = "ICU "+(maj);
                                System.err.println("    .. " + milestoneOf + " is the release of " + truncVersion);
                            } else {
                                milestoneOf = " (update "+micr+"."+patch+")";
                                result = "ICU "+(maj);
                                System.err.println("    .. " + milestoneOf + " is an update to  " + truncVersion);
                            }
                            // always truncate to major # for comparing tags.
                            result = truncVersion;
                        } else {
                            // old scheme - 1.0.* .. 4.8.*
                            String truncVersion = "ICU " + maj+"."+min;
                            if((min%2)==1) {
                                milestoneOf = " ("+maj+"."+(min+1)+"m"+micr+")";
                                truncVersion = "ICU "+(maj)+"."+(min+1);
                                System.err.println("    .. " + milestoneOf + " is a milestone towards " + truncVersion);
                            } else if(micr==0 && patch==0) {
                                System.err.println("    .. " + milestoneOf + " is the release of " + truncVersion);
                            } else {
                                milestoneOf = " (update "+micr+"."+patch+")";
                                System.err.println("    .. " + milestoneOf + " is an update to " + truncVersion);
                            }
                            result = truncVersion;
                        }
                        if(whichVer.equals("new")) {
                            rightMilestone = milestoneOf;
                        } else {
                            leftMilestone = milestoneOf;
                        }
                    }
                }
                
            }
            //dumpNode(defines,"");
        } catch(Throwable t) {
            t.printStackTrace();
            System.err.println("Warning: Couldn't get " + whichVer+  " version from "+ UVERSION + " - reverting to " + prevVer);
            result = prevVer;
        }
        
        if(result != null) {
        	
        }
        
        if(prevVer != null) {
            if(result != null) {
                if(!result.equals(prevVer)) { 
                    System.err.println("Note: Detected " + result + " version but we'll use your requested --"+whichVer+"ver "+prevVer);
                    result = prevVer;
                    if(!rightMilestone.isEmpty()&&whichVer.equals("new")) {
                        System.err.println(" .. ignoring milestone indicator " + rightMilestone);
                        rightMilestone = "";
                    }
                    if(!leftMilestone.isEmpty()&&!whichVer.equals("new")) {
                        leftMilestone="";
                    }
                } else {
                    System.err.println("Note: You don't need to use  '--"+whichVer+"ver "+result+"' anymore - we detected it correctly.");
                }
            } else {
                System.err.println("Note: Didn't detect version so we'll use your requested --"+whichVer+"ver "+prevVer);
            	result = prevVer;
            	if(!rightMilestone.isEmpty()&&whichVer.equals("new")) {
            		System.err.println(" .. ignoring milestone indicator " + rightMilestone);
            		rightMilestone = "";
            	}
                if(!leftMilestone.isEmpty()&&!whichVer.equals("new")) {
                    leftMilestone="";
                }
            }
        }
        
        if(result == null) {
        	System.err.println("prevVer="+prevVer);
            System.err.println("Error: You'll need to use the option  \"--"+whichVer+"ver\"  because we could not detect an ICU version in " + UVERSION );
            throw new InternalError("Error: You'll need to use the option  \"--"+whichVer+"ver\"  because we could not detect an ICU version in " + UVERSION );
        }
        
        
        
        return result;
    }
    
    private static void printUsage(){
        System.out.println("Usage: StableAPI option* target*");
        System.out.println();
        System.out.println("Options:");
        System.out.println("    --help          Print this text");
        System.out.println("    --oldver        Version of old version of ICU (optional)");
        System.out.println("    --olddir        Directory that contains xml docs of old version");
        System.out.println("    --newver        Version of new version of ICU (optional)");
        System.out.println("    --newdir        Directory that contains xml docs of new version");
        System.out.println("    --cxslt         XSLT file for C docs");
        System.out.println("    --cppxslt       XSLT file for C++ docs");
        System.out.println("    --reportxslt    XSLT file for report docs");
        System.out.println("    --resultfile    Output file");
        System.exit(-1);
    }

    static String getAttr(Node node, String attrName){
    	if(node.getAttributes()==null && node.getNodeType()==3) {
//    		return "(text node 3)";
    		return "(Node: " + node.toString() + " )";
//    		return node.getFirstChild().getAttributes().getNamedItem(attrName).getNodeValue();
    	}
    	
        try {
        	return node.getAttributes().getNamedItem(attrName).getNodeValue();
        } catch(NullPointerException npe) {
        	if(node.getAttributes()==null)  {
        		throw new InternalError("[no attributes Can't get attr "+attrName +" out of node " + node.getNodeName()+":"+node.getNodeType()+":"+node.getNodeValue()+"@"+node.getTextContent());
        	} else if(node.getAttributes().getNamedItem(attrName)==null) {
        		return null; 
        		//throw new InternalError("No attribute named: "+attrName);
        	} else {
        		System.err.println("Can't get attr "+attrName+": "+npe.toString());
        	}
        	npe.printStackTrace();
        	throw new InternalError("Can't get attr "+attrName);
        }
    }
    
    static String getAttr(NamedNodeMap attrList, String attrName){
        return attrList.getNamedItem(attrName).getNodeValue();
    }
    
    static class Function implements Comparable<Function> {
        public String prototype;
        public String id;
        public String status;
        public String version;
        public String file;
        public String comparableName;
        public boolean equals(Function right){
            return this.prototype.equals(right.prototype);
        }
        static Function fromXml(Node n){
            Function f = new Function();
            f.prototype = getAttr(n, "prototype");
            
            if("yes".equals(getAttr(n, "static"))&&!f.prototype.contains("static")) {
            	f.prototype = "static ".concat(f.prototype);
            }
             
            f.id = getAttr(n, "id");
            f.status = getAttr(n, "status");
            f.version = trimICU(getAttr(n, "version"));
            f.file = getAttr(n, "file");
            f.purifyPrototype();
            
            f.simplifyPrototype();

            if(f.file == null) {
            	f.file = "{null}";
            } else {
            	f.file = Function.getBasename(f.file);
            }
            f.comparableName = f.comparableName();
            return f;
        }
        
        /**
         * Convert string to basename.
         * @param str
         * @return
         */
        private static String getBasename(String str){
            int i = str.lastIndexOf("/");
            str = i == -1 ? str : str.substring(i+1);
            return str;
        }
        

        static private String replList[] = {  "[ ]*\\([ ]*void[ ]*\\)[ ]*",   "()",  // cleanup
                                              " , ", ", ",                // cleanup
                                              "[ ]*=[ ]*0[ ]*$", "=0",      // cleanup pure virtual
                                              "\\)[ ]*const", ") const",  // This just cleans up the spacing.

                                              "^const [ ]*", "const ", // cleanup
                                              //"([,)])[ ]*const [ ]*", "\1",  // TODO: notify about this difference, separately - remove const from param
            						};

        /**
         * these are noted as deltas.
         */
        static private String simplifyList[] = { 
            "[ ]*=[ ]*0[ ]*$", "",      // remove pure virtual - TODO: notify about this difference, separately
            "\\)[ ]*const[ ]*$", ")",  // TODO: notify about this difference, separately - remove const from function type
        };

        /**
         * Special cases:
         * 
         * Remove the status attribute embedded in the C prototype
         * 
         * Remove the virtual keyword in Cpp prototype
         */
        private void purifyPrototype(){
            //refer to 'umachine.h'
            String statusList[] = {"U_CAPI", "U_STABLE", "U_DRAFT", "U_DEPRECATED", "U_OBSOLETE", "U_INTERNAL", "virtual", "U_EXPORT2", "U_I18N_API", "U_COMMON_API" };
            for (int i = 0; i < statusList.length; i++) {
                String s = statusList[i];
                prototype = prototype.replaceAll(s,"");
                prototype = prototype.trim();
            }
            
            for (int i = 0; i < replList.length; i+= 2) {
                prototype = prototype.replaceAll(replList[i+0],replList[i+1]);
            }
            
            
            prototype = prototype.trim();

            // Now, remove parameter names!
            StringBuffer out = new StringBuffer();
            StringBuffer in = new StringBuffer(prototype);
            int openParen = in.indexOf("(");
            int closeParen = in.lastIndexOf(")");
            
            if(openParen==-1 || closeParen==-1) return; // exit, malformed?
            if(openParen+1==closeParen) return; // exit: ()
            
            out.append(in, 0, openParen+1); // prelude
                        
            for(int left = openParen+1; left<closeParen;) {
            	int right = in.indexOf(",", left+1); // right edge
            	if(right>=closeParen || right==-1 )  right=closeParen; // found last comma
            	
            //	System.err.println("Considering  " + left + " / " + right + " - " + closeParen +  " : "  + in.substring(left, right));
            	
            	if(left==right) continue; 
            	
            	// find variable name
            	int rightCh = right-1;
            	if(rightCh==left) { // 1 ch- break
            		out.append(in,left,right);
            		continue;
            	}
            	// eat whitespace at right
            	int nameEndCh = rightCh;
            	while(nameEndCh>left && Character.isWhitespace(in.charAt(nameEndCh))) {
            		nameEndCh--;
            	}
            	int nameStartCh = nameEndCh;
            	while(nameStartCh>left && Character.isJavaIdentifierPart(in.charAt(nameStartCh))) {
            		nameStartCh--;
            	}
            	
            	// now, did we find something to skip?
            	if(nameStartCh>left && nameEndCh>nameStartCh) {
            		out.append(in, left, nameStartCh+1);
            	} else {
            		// pass through
            		out.append(in, left, right);
            	}
            	
            	left = right;
            }
            
            out.append(in, closeParen, in.length()); // postlude
            
            // Delete any doubled whitespace.
            for(int p=1;p<out.length();p++) {
                char prev = out.charAt(p-1); 
            	if(Character.isWhitespace(prev)) {
            		while (out.length()>p&&(Character.isWhitespace(out.charAt(p)))) {
            			out.deleteCharAt(p);
            		}
            		if(out.length()>p) {
            			// any trailings to delete?
            			char curr = out.charAt(p);
            			if(curr==',' || curr==')' || curr=='*' || curr=='&') { // delete spaces before these.
            				out.deleteCharAt(--p);
            				continue;
            			}
            		}
            	}
            }
            
          //  System.err.println(prototype+" -> " + out.toString());
            prototype = out.toString();
        }

        private void simplifyPrototype() {
            final String prototype0 = prototype;
            for (int i = 0; i < simplifyList.length; i+= 2) {
                prototype = prototype.replaceAll(simplifyList[i+0],simplifyList[i+1]);
            }
            if(!prototype0.equals(prototype)) {
                addSimplification(prototype0, prototype);
            }
        }
//        private Element toXml(Document doc){
//            Element  ele = doc.createElement("func");
//            ele.setAttribute("prototype", prototype);
//            ele.setAttribute("id", id);
//            ele.setAttribute("status", status);
//            return ele;
//        }
		public int compareTo(Function o) {
			return comparableName.compareTo(((Function)o).comparableName);
		}
		public String comparableName() { 
			return file+"|"+prototype+"|"+status+"|"+version+"|"+id;
		}
    }
    
    static class JoinedFunction implements Comparable<JoinedFunction> {
        public String prototype;
        public String leftRefId;
        public String leftStatus;
        public String leftVersion;
        public String rightVersion;
        public String leftFile;
        public String rightRefId;
        public String rightStatus;
        public String rightFile;
        
        public String comparableName;
        
        static JoinedFunction fromLeftFun(Function left){
            JoinedFunction u = new JoinedFunction();
            u.prototype = left.prototype;
            u.leftRefId = left.id;
            u.leftStatus = left.status;
            u.leftFile = left.file;
            u.rightRefId = nul;
           // u.rightVersion = nul;
            u.leftVersion = left.version;
            u.rightStatus = nul;
            u.rightFile = nul;
            u.comparableName = left.comparableName;
            return u;
        }
    
        static JoinedFunction fromRightFun(Function right){
            JoinedFunction u = new JoinedFunction();
            u.prototype = right.prototype;
            u.leftRefId = nul;
            u.leftStatus = nul;
            u.leftFile = nul;
           // u.leftVersion = nul;
            u.rightVersion = right.version;
            u.rightRefId = right.id;
            u.rightStatus = right.status;
            u.rightFile = right.file;
            u.comparableName = right.comparableName;
            return u;
        }
        
        static JoinedFunction fromTwoFun(Function left, Function right){
            if (!left.equals(right)) throw new Error();
            JoinedFunction u = new JoinedFunction();
            u.prototype = left.prototype;
            u.leftRefId = left.id;
            u.leftStatus = left.status;
            u.leftFile = left.file;
            u.rightRefId = right.id;
            u.rightStatus = right.status;
            u.leftVersion = left.version;
            u.rightVersion = right.version;
            u.rightFile = right.file;
            u.comparableName = left.comparableName+"+"+right.comparableName;
            return u;
        }

        Element toXml(Document doc){
            Element  ele = doc.createElement("func");
            ele.setAttribute("prototype", formatCode(prototype));
//            ele.setAttribute("leftRefId", leftRefId);
            
            ele.setAttribute("leftStatus", leftStatus);
//            ele.setAttribute("rightRefId", rightRefId);
            ele.setAttribute("rightStatus", rightStatus);
            ele.setAttribute("leftVersion", leftVersion);
//            ele.setAttribute("rightRefId", rightRefId);
            ele.setAttribute("rightVersion", rightVersion);
            
            
//            String f = rightRefId.equals(nul) ? leftRefId : rightRefId;
//            int tail = f.indexOf("_");
//            f = tail != -1 ? f.substring(0, tail) : f;
//            f = f.startsWith("class") ? f.replaceFirst("class","") : f;
            String f = rightFile.equals(nul) ? leftFile : rightFile;
            ele.setAttribute("file", f);
            return ele;
        }
        

		public int compareTo(JoinedFunction o) {
			return comparableName.compareTo(o.comparableName);
		}
		
        public boolean equals(Function right){
            return this.prototype.equals(right.prototype);
        }
    }

    TransformerFactory transFac = TransformerFactory.newInstance();
    Transformer makeTransformer(InputStream is, String name) {
    	if(is==null) {
    		throw new InternalError("No inputstream set for " + name);
    	}
    	System.err.println("Transforming from: " + name);
    	Transformer t;
		try {
//			// check the prolog
//			if(is.markSupported())  try {
//				is.mark(100);
//				int b = is.read();
//				is.reset();
//				System.err.println("Read byte: == " + Integer.toHexString(b));
//			} catch(Throwable th) {
//				System.err.println(" ( couldn't read a byte: " + th.toString()+ " )");
//			} else {
//				System.err.println(" ( couldn't set mark)");
//			}
			StreamSource ss = new StreamSource(is);
			ss.setSystemId(new File("."));
			t = transFac.newTransformer(ss);
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
			throw new InternalError("Couldn't make transformer for " + name + " - " + e.getMessageAndLocation());			
		}
    	if(t == null) {
    		throw new InternalError("Couldn't make transformer for " + name);
    	}
    	return t;
    }
    private void reportSelectedFun(Node joinedNode) throws TransformerException, ParserConfigurationException, SAXException, IOException{
        Transformer report = makeTransformer(reportXslStream, RPTXSLT);
        //report.setParameter("leftStatus", leftStatus);
        report.setParameter("leftVer", leftVer);
//        report.setParameter("rightStatus", rightStatus);
        report.setParameter("ourYear", new Integer(new java.util.GregorianCalendar().get(java.util.Calendar.YEAR)));
        report.setParameter("rightVer", rightVer);
        report.setParameter("rightMilestone", rightMilestone);
        report.setParameter("leftMilestone", leftMilestone);
        report.setParameter("dateTime", new GregorianCalendar().getTime());
        report.setParameter("nul", nul);
        
        DOMSource src = new DOMSource(joinedNode);

        Result res = new StreamResult(resultFile);
//        DOMResult res = new DOMResult();
        report.transform(src, res);
//        dumpNode(res.getNode(),"");
    }
    
    private Set<JoinedFunction> getFullList(InputStream dumpXsltStream, String dumpXsltFile) throws TransformerException, ParserConfigurationException, XPathExpressionException, SAXException, IOException{
        // prepare transformer
        XPath xpath = XPathFactory.newInstance().newXPath();
        String expression = "/list";
        Transformer transformer = makeTransformer(dumpXsltStream, dumpXsltFile);

        //        InputSource leftSource = new InputSource(leftDir + "index.xml");
        DOMSource leftIndex = new DOMSource(getDocument(new File(leftDir,INDEX_XML)));
        DOMResult leftResult = new DOMResult();
        transformer.setParameter(DOC_FOLDER, leftDir);
        transformer.transform(leftIndex, leftResult);

//        Node leftList = XPathAPI.selectSingleNode(leftResult.getNode(),"/list");
        Node leftList = (Node)xpath.evaluate(expression, leftResult.getNode(), XPathConstants.NODE);
        if(leftList==null) {
           	//dumpNode(xsltSource.getNode());
          	dumpNode(leftResult.getNode());
//        	dumpNode(leftIndex.getNode());
        	System.out.flush();
        	System.err.flush();
        	throw new InternalError("getFullList("+dumpXsltFile.toString()+") returned a null left "+expression);
        }
        
        xpath.reset(); // reuse
        
        DOMSource rightIndex = new DOMSource(getDocument(new File(rightDir,INDEX_XML)));
        DOMResult rightResult = new DOMResult();
        transformer.setParameter(DOC_FOLDER, rightDir);
        System.err.println("Loading: "+dumpXsltFile.toString());
        transformer.transform(rightIndex, rightResult);
        System.err.println("   .. loaded: "+dumpXsltFile.toString());
        Node rightList = (Node)xpath.evaluate(expression, rightResult.getNode(), XPathConstants.NODE);
        if(rightList==null) {
        	throw new InternalError("getFullList("+dumpXsltFile.toString()+") returned a null right "+expression);
        }
//        dumpNode(rightList,"");
        
        
        Set<Function> leftSet = nodeToSet(leftList);
        Set<Function> rightSet = nodeToSet(rightList);
        Set<JoinedFunction> joined = fullJoin(leftSet, rightSet);
        return joined;
//        joinedNode = setToNode(joined);
//        dumpNode(joinedNode,"");
//        return joinedNode;
    }

    /**
     * @param node
     * @return      Set<Fun>
     */
    private Set<Function> nodeToSet(Node node){
        Set<Function> s = new TreeSet<Function>();
        NodeList list = node.getChildNodes();
        for (int i = 0; i < list.getLength(); i++) {
            Node n = list.item(i);
            s.add(Function.fromXml(n));
        }
        return s;
    }

    /**
     * @param set       Set<JoinedFun>
     * @return
     * @throws ParserConfigurationException
     */
    private Node setToNode(Set<JoinedFunction> set) throws ParserConfigurationException{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        Document doc  = dbf.newDocumentBuilder().newDocument();
        Element root = doc.createElement("list");
        doc.appendChild(root);
        for (Iterator<JoinedFunction> iter = set.iterator(); iter.hasNext();) {
            JoinedFunction fun = iter.next();
            root.appendChild(fun.toXml(doc));
        }
        
        // add the 'changed' stuff
        Element root2 = doc.createElement("simplifications");
        root.appendChild(root2);
        {
        	for(String simplification : getChangedSimplifications()) {
        		Element subSimplification = doc.createElement("simplification");
        		Element baseElement = doc.createElement("base");
        		baseElement.appendChild(doc.createTextNode(simplification));
        		subSimplification.appendChild(baseElement);
        		
        		root2.appendChild(subSimplification);
        		
        		for(String change : simplifications.get(simplification)) {
        			Element changeElement = doc.createElement("change");
        			changeElement.appendChild(doc.createTextNode(change));
        			subSimplification.appendChild(changeElement);
        		}
	       	}
        }
        
        return doc;
    }

    /**
     * full-join two Set on 'prototype' 
     * 
     * @param left     Set<Fun>
     * @param right    Set<Fun>
     * @return          Set<JoinedFun>
     */
    private static Set<JoinedFunction> fullJoin(Set<Function> left, Set<Function> right){

        Set<JoinedFunction> joined = new TreeSet<JoinedFunction>(); //Set<JoinedFun>
        Set<Function> common = new TreeSet<Function>(); //Set<Fun>
        for (Iterator<Function> iter1 = left.iterator(); iter1.hasNext();) {
            Function f1 = iter1.next();
//            if (f1.prototype.matches(".*Transliterator::.*")){
//                System.err.println("left: " + f1.prototype);
//                System.err.println("left: " + f1.status);
//            }
            for (Iterator<Function> iter2 = right.iterator(); iter2.hasNext();) {
                Function f2 = iter2.next();
//                if ( f1.prototype.matches(".*filteredTransliterate.*")
//                  && f2.prototype.matches(".*filteredTransliterate.*")){
//                    System.err.println("right: " + f2.prototype);
//                    System.err.println("right: " + f2.status);
//                    System.err.println(f1.prototype.equals(f2.prototype));
//                    System.err.println(f1.prototype.getBytes()[0]);
//                    System.err.println(f2.prototype.getBytes()[0]);
//                }
                if (f1.equals(f2)) {
                    // should add left item to common set
                    // since we will remove common items with left set later
                    common.add(f1);
                    joined.add(JoinedFunction.fromTwoFun(f1, f2));
                    right.remove(f2);
                    break;
                } 
            }
        }

        for (Iterator<Function> iter = common.iterator(); iter.hasNext();) {
            Function f = iter.next();
            left.remove(f);
        }
        
        for (Iterator<Function> iter = left.iterator(); iter.hasNext();) {
            Function f = iter.next();
            joined.add(JoinedFunction.fromLeftFun(f));
        }
        
        for (Iterator<Function> iter = right.iterator(); iter.hasNext();) {
            Function f = iter.next();
            joined.add(JoinedFunction.fromRightFun(f));
        }
        return joined;
    }
    
    private static void dumpNode(Node n) {
    	dumpNode(n,"");
    }
    /**
     * Dump out a node for debugging. Recursive fcn
     * @param n
     * @param pre
     */
    private static void dumpNode(Node n, String pre) {
    	String opre = pre;
		pre += " ";
		System.out.print(opre + "<" + n.getNodeName() );
		// dump attribute
		NamedNodeMap attr = n.getAttributes();
		if (attr != null) {
			for (int i = 0; i < attr.getLength(); i++) {
				System.out.print("\n"+pre+"   "+attr.item(i).getNodeName()+"=\"" + attr.item(i).getNodeValue()+"\"");
			}
		}
		System.out.println(">");

		// dump value
		String v = pre + n.getNodeValue();
		if (n.getNodeType() == Node.TEXT_NODE)
			System.out.println(v);

		// dump sub nodes
		NodeList nList = n.getChildNodes();
		for (int i = 0; i < nList.getLength(); i++) {
			Node ln = nList.item(i);
			dumpNode(ln, pre + " ");
		}
		System.out.println(opre + "</" + n.getNodeName() + ">");
	}
    
    private static DocumentBuilder theBuilder = null;
    private static DocumentBuilderFactory dbf  = null;
    private synchronized static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
    	if(theBuilder == null) {
            dbf = DocumentBuilderFactory.newInstance();
            theBuilder = dbf.newDocumentBuilder();
    	}
    	return theBuilder;
    }
    
    private static Document getDocument(File file) throws ParserConfigurationException, SAXException, IOException{
        FileInputStream fis = new FileInputStream(file);
        InputSource inputSource = new InputSource(fis);
        Document doc = getDocumentBuilder().parse(inputSource);
        return doc;
    }
    static boolean tried = false;
    static Formatter aFormatter = null;
    
    public interface Formatter {
    	public String formatCode(String s);
    }
    

    public static String format_keywords[] = {
    	"enum","#define","static"
    };
    
    /**
     * Attempt to use a pretty formatter
     * @param prototype2
     * @return
     */
	public static String formatCode(String prototype2) {
		if(!tried) {
			String theFormatter = StableAPI.class.getPackage().getName()+".CodeFormatter";
			try {
				@SuppressWarnings("unchecked")
				Class<Formatter> formatClass = (Class<Formatter>) Class.forName(theFormatter);
				aFormatter = (Formatter) formatClass.newInstance();
			} catch (Exception e) {
				System.err.println("Note: Couldn't load " + theFormatter);
				aFormatter = new Formatter() {

					public String formatCode(String s) {
						String str = HTMLSafe(s.trim());
						for(String keyword : format_keywords) {
							if(str.startsWith(keyword)) {
								str = str.replaceFirst(keyword, "<tt>"+keyword+"</tt>");
							}
						}
						return str;
					}
					
				};
			}
			tried = true;
		}
		if(aFormatter != null) {
			return aFormatter.formatCode(prototype2);
		} else {
			return HTMLSafe(prototype2);
		}
	}

    public static String HTMLSafe(String s) {
        if(s==null) return null;
        
        return 
            s.replaceAll("&","&amp;")
             .replaceAll("<","&lt;")
             .replaceAll(">","&gt;")
             .replaceAll("\"","&quot;");
    }
    
	
}
