/*
 **********************************************************************
 * Copyright (c) 2006-2013, 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 notFound = "(missing)";

    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;
                        System.err.println(" == ["+vers.toString()+"] " + maj + " . " + min + " . " + micr + " . " + patch );
                        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 #"+(min-1)+": "+result.substring(4)+")";
                                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 = notFound;
           // u.rightVersion = nul;
            u.leftVersion = left.version;
            u.rightStatus = notFound;
            u.rightFile = notFound;
            u.comparableName = left.comparableName;
            return u;
        }

        static JoinedFunction fromRightFun(Function right){
            JoinedFunction u = new JoinedFunction();
            u.prototype = right.prototype;
            u.leftRefId = notFound;
            u.leftStatus = notFound;
            u.leftFile = notFound;
           // 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(notFound) ? 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(notFound) ? 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("notFound", notFound);

        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;");
    }


}
