package jdiff;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javadoc;
import org.apache.tools.ant.taskdefs.Javadoc.DocletInfo;
import org.apache.tools.ant.taskdefs.Javadoc.DocletParam;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.Path;

/**
 * An Ant task to produce a simple JDiff report. More complex reports still
 * need parameters that are controlled by the Ant Javadoc task.
 */
public class JDiffAntTask {

    public void execute() throws BuildException {
	jdiffHome = project.getProperty("JDIFF_HOME");
	if (jdiffHome == null || jdiffHome.compareTo("") == 0 | 
	    jdiffHome.compareTo("(not set)") == 0) {
	    throw new BuildException("Error: invalid JDIFF_HOME property. Set it in the build file to the directory where jdiff is installed");
	}
        project.log(" JDiff home: " + jdiffHome, Project.MSG_INFO);

	jdiffClassPath = jdiffHome + DIR_SEP + "jdiff.jar" +
	    System.getProperty("path.separator") +
	    jdiffHome + DIR_SEP + "xerces.jar";

	// TODO detect and set verboseAnt

	// Create, if necessary, the directory for the JDiff HTML report
        if (!destdir.mkdir() && !destdir.exists()) {
	    throw new BuildException(getDestdir() + " is not a valid directory");
	} else {
	    project.log(" Report location: " + getDestdir() + DIR_SEP 
			+ "changes.html", Project.MSG_INFO);
	}
	// Could also output the other parameters used for JDiff here
 	
	// Check that there are indeed two projects to compare. If there
	// are no directories in the project, let Javadoc do the complaining
	if (oldProject == null || newProject == null) {
	    throw new BuildException("Error: two projects are needed, one <old> and one <new>");
	}

	/*
	// Display the directories being compared, and some name information
	if (getVerbose()) {
	    project.log("Older version: " + oldProject.getName(), 
			Project.MSG_INFO);
	    project.log("Included directories for older version:", 
			Project.MSG_INFO);
	    DirectoryScanner ds = 
		oldProject.getDirset().getDirectoryScanner(project);
	    String[] files = ds.getIncludedDirectories();
	    for (int i = 0; i < files.length; i++) {
		project.log(" " + files[i], Project.MSG_INFO);
	    }
	    ds = null;
	    
	    project.log("Newer version: " + newProject.getName(), 
			Project.MSG_INFO);
	    project.log("Included directories for newer version:", 
			Project.MSG_INFO);
	    ds = newProject.getDirset().getDirectoryScanner(project);
	    files = ds.getIncludedDirectories();
	    for (int i = 0; i < files.length; i++) {
		project.log(" " + files[i], Project.MSG_INFO);
	    }
	}
	*/

	// Call Javadoc twice to generate Javadoc for each project
	generateJavadoc(oldProject);
	generateJavadoc(newProject);

	// Call Javadoc three times for JDiff.
	generateXML(oldProject);
	generateXML(newProject);
	compareXML(oldProject.getName(), newProject.getName());

	// Repeat some useful information
	project.log(" Report location: " + getDestdir() + DIR_SEP 
		    + "changes.html", Project.MSG_INFO);
    }

    /**
     * Convenient method to create a Javadoc task, configure it and run it
     * to generate the XML representation of a project's source files.
     *
     * @param proj The current Project
     */
    protected void generateXML(ProjectInfo proj) {
	String apiname = proj.getName();
	Javadoc jd = initJavadoc("Analyzing " + apiname);
	jd.setDestdir(getDestdir());
	addSourcePaths(jd, proj);

	// Tell Javadoc which packages we want to scan. 
	// JDiff works with packagenames, not sourcefiles.
	jd.setPackagenames(getPackageList(proj));
	
	// Create the DocletInfo first so we have a way to use it to add params
	DocletInfo dInfo = jd.createDoclet();
	jd.setDoclet("jdiff.JDiff");
	jd.setDocletPath(new Path(project, jdiffClassPath));
	
	// Now set up some parameters for the JDiff doclet.
	DocletParam dp1 = dInfo.createParam();
	dp1.setName("-apiname");
	dp1.setValue(apiname);
	DocletParam dp2 = dInfo.createParam();
	dp2.setName("-baseURI");
	dp2.setValue("http://www.w3.org");
	// Put the generated file in the same directory as the report
	DocletParam dp3 = dInfo.createParam();
	dp3.setName("-apidir");
	dp3.setValue(getDestdir().toString());
	
	// Execute the Javadoc command to generate the XML file.
	jd.perform();
    }

    /**
     * Convenient method to create a Javadoc task, configure it and run it
     * to compare the XML representations of two instances of a project's 
     * source files, and generate an HTML report summarizing the differences.
     *
     * @param oldapiname The name of the older version of the project
     * @param newapiname The name of the newer version of the project
     */
    protected void compareXML(String oldapiname, String newapiname) {
	Javadoc jd = initJavadoc("Comparing versions");
	jd.setDestdir(getDestdir());
	jd.setPrivate(true);

	// Tell Javadoc which files we want to scan - a dummy file in this case
	jd.setSourcefiles(jdiffHome + DIR_SEP + "Null.java");
	
	// Create the DocletInfo first so we have a way to use it to add params
	DocletInfo dInfo = jd.createDoclet();
	jd.setDoclet("jdiff.JDiff");
	jd.setDocletPath(new Path(project, jdiffClassPath));
	
	// Now set up some parameters for the JDiff doclet.
	DocletParam dp1 = dInfo.createParam();
	dp1.setName("-oldapi");
	dp1.setValue(oldapiname);
	DocletParam dp2 = dInfo.createParam();
	dp2.setName("-newapi");
	dp2.setValue(newapiname);
	// Get the generated XML files from the same directory as the report
	DocletParam dp3 = dInfo.createParam();
	dp3.setName("-oldapidir");
	dp3.setValue(getDestdir().toString());
	DocletParam dp4 = dInfo.createParam();
	dp4.setName("-newapidir");
	dp4.setValue(getDestdir().toString());

	// Assume that Javadoc reports already exist in ../"apiname"
	DocletParam dp5 = dInfo.createParam();
	dp5.setName("-javadocold");
	dp5.setValue(".." + DIR_SEP + oldapiname + DIR_SEP);
	DocletParam dp6 = dInfo.createParam();
	dp6.setName("-javadocnew");
	dp6.setValue(".." + DIR_SEP + newapiname + DIR_SEP);
	
	if (getStats()) {
	    // There are no arguments to this argument
	    dInfo.createParam().setName("-stats");
	    // We also have to copy two image files for the stats pages
	    copyFile(jdiffHome + DIR_SEP + "black.gif",
		     getDestdir().toString() + DIR_SEP + "black.gif");
	    copyFile(jdiffHome + DIR_SEP + "background.gif",
		     getDestdir().toString() + DIR_SEP + "background.gif");
	}
	
	if (getDocchanges()) {
	    // There are no arguments to this argument
	    dInfo.createParam().setName("-docchanges");
	}

	// Execute the Javadoc command to compare the two XML files
	jd.perform();
    }

    /**
     * Generate the Javadoc for the project. If you want to generate
     * the Javadoc report for the project with different parameters from the
     * simple ones used here, then use the Javadoc Ant task directly, and 
     * set the javadoc attribute to the "old" or "new" element.
     *
     * @param proj The current Project
     */
    protected void generateJavadoc(ProjectInfo proj) {	
	String javadoc = proj.getJavadoc();
	if (javadoc != null && javadoc.compareTo("generated") != 0) {
	    project.log("Configured to use existing Javadoc located in " +  
			javadoc, Project.MSG_INFO);
	    return;
	}

	String apiname = proj.getName();
	Javadoc jd = initJavadoc("Javadoc for " + apiname);
	jd.setDestdir(new File(getDestdir().toString() + DIR_SEP + apiname));
	addSourcePaths(jd, proj);

	jd.setPrivate(true);
	jd.setPackagenames(getPackageList(proj));

	// Execute the Javadoc command to generate a regular Javadoc report
	jd.perform();
    }

    /**
     * Create a fresh new Javadoc task object and initialize it.
     *
     * @param logMsg String which appears as a prefix in the Ant log
     * @return The new task.Javadoc object
     */
    protected Javadoc initJavadoc(String logMsg) {
	Javadoc jd = new Javadoc();
	jd.setProject(project); // Vital, otherwise Ant crashes
	jd.setTaskName(logMsg);
	jd.setSource(getSource()); // So we can set the language version
	jd.init();

	// Set up some common parameters for the Javadoc task
	if (verboseAnt) {
	    jd.setVerbose(true);
	}
	return jd;
    }

    /**
     * Add the root directories for the given project to the Javadoc 
     * sourcepath.
     */
    protected void addSourcePaths(Javadoc jd, ProjectInfo proj) {
	Vector dirSets = proj.getDirsets();
	int numDirSets = dirSets.size();
	for (int i = 0; i < numDirSets; i++) {
	    DirSet dirSet = (DirSet)dirSets.elementAt(i);
	    jd.setSourcepath(new Path(project, dirSet.getDir(project).toString()));
	}
    }

    /**
     * Return the comma-separated list of packages. The list is
     * generated from Ant DirSet tasks, and includes all directories
     * in a hierarchy, e.g. com, com/acme. com/acme/foo. Duplicates are 
     * ignored.
     */
    protected String getPackageList(ProjectInfo proj) throws BuildException {
	String packageList = ""; 
	java.lang.StringBuffer sb = new StringBuffer();
	Vector dirSets = proj.getDirsets();
	int numDirSets = dirSets.size();
	boolean addComma = false;
	for (int i = 0; i < numDirSets; i++) {
	    DirSet dirSet = (DirSet)dirSets.elementAt(i);
	    DirectoryScanner dirScanner = dirSet.getDirectoryScanner(project);
	    String[] files = dirScanner.getIncludedDirectories();
	    for (int j = 0; j < files.length; j++) {
		if (!addComma){
		    addComma = true;
		} else {
		    sb.append(",");
		}
		sb.append(files[j]);
	    }
	}
	packageList = sb.toString();
	if (packageList.compareTo("") == 0) {
	    throw new BuildException("Error: no packages found to scan");
	}
	project.log(" Package list: " + packageList, Project.MSG_INFO);
	
	return packageList;
    }

    /**
     * Copy a file from src to dst. Also checks that "destdir/changes" exists
     */
    protected void copyFile(String src, String dst){
	File srcFile = new File(src);
	File dstFile = new File(dst);
	try {
	    File reportSubdir = new File(getDestdir().toString() + 
					 DIR_SEP + "changes");
	    if (!reportSubdir.mkdir() && !reportSubdir.exists()) {
		project.log("Warning: unable to create " + reportSubdir,
			    Project.MSG_WARN);
	    }

	    InputStream in = new FileInputStream(src);
	    OutputStream out = new FileOutputStream(dst);
		
	    // Transfer bytes from in to out
	    byte[] buf = new byte[1024];
	    int len;
	    while ((len = in.read(buf)) > 0) {
		out.write(buf, 0, len);
	    }
	    in.close();
	    out.close();
	} catch (java.io.FileNotFoundException fnfe) {
	    project.log("Warning: unable to copy " + src.toString() + 
			" to " + dst.toString(), Project.MSG_WARN);
	    // Discard the exception
	} catch (java.io.IOException ioe) {
	    project.log("Warning: unable to copy " + src.toString() + 
			" to " + dst.toString(), Project.MSG_WARN);
	    // Discard the exception
	}
    }

    /**
     * The JDiff Ant task does not inherit from an Ant task, such as the 
     * Javadoc task, though this is usually how most Tasks are
     * written. This is because JDiff needs to run Javadoc three times
     * (twice for generating XML, once for generating HTML). The
     * Javadoc task has not easy way to reset its list of packages, so
     * we needed to be able to crate new Javadoc task objects.
     *
     * Note: Don't confuse this class with the ProjectInfo used by JDiff. 
     * This Project class is from Ant.
     */
    private Project project;

    /**
     * Used as part of Ant's startup.
     */
    public void setProject(Project proj) {
        project = proj;
    }

    /** 
     * Ferward or backward slash, as appropriate.
     */
    static String DIR_SEP = System.getProperty("file.separator");

    /**
     * JDIFF_HOME must be set as a property in the Ant build file.
     * It should be set to the root JDiff directory, ie. the one where 
     * jdiff.jar is found.
     */
    private String jdiffHome = "(not set)";

    /**
     * The classpath used by Javadoc to find jdiff.jar and xerces.jar.
     */
    private String jdiffClassPath = "(not set)";

    /* ***************************************************************** */
    /* * Objects and methods which are related to attributes           * */
    /* ***************************************************************** */

    /** 
     * The destination directory for the generated report.
     * The default is "./jdiff_report".
     */
    private File destdir = new File("jdiff_report");

    /**
     * Used to store the destdir attribute of the JDiff task XML element.
     */
    public void setDestdir(File value) {
	this.destdir = value;
    }

    public File getDestdir() {
	return this.destdir;
    }

    /** 
     * Increases the JDiff Ant task logging verbosity if set with "yes", "on" 
     * or true". Default has to be false.
     * To increase verbosity of Javadoc, start Ant with -v or -verbose.
     */ 
    private boolean verbose = false;

    public void setVerbose(boolean value) {
	this.verbose = value;
    }

    public boolean getVerbose() {
	return this.verbose;
    }

    /** 
     * Set if ant was started with -v or -verbose 
     */
    private boolean verboseAnt = false;

    /** 
     * Add the -docchanges argument, to track changes in Javadoc documentation
     * as well as changes in classes etc.
     */ 
    private boolean docchanges = false;

    public void setDocchanges(boolean value) {
	this.docchanges = value;
    }

    public boolean getDocchanges() {
	return this.docchanges;
    }

    /** 
     * Add statistics to the report if set. Default can only be false.
     */ 
    private boolean stats = false;

    public void setStats(boolean value) {
	this.stats = value;
    }

    public boolean getStats() {
	return this.stats;
    }

    /**
     * Allow the source language version to be specified.
     */
    private String source = "1.5"; // Default is 1.5, so generics will work
    
    public void setSource(String source) {
        this.source = source;
    }
    
    public String getSource() {
        return source;
    }

    /* ***************************************************************** */
    /* * Classes and objects which are related to elements             * */
    /* ***************************************************************** */

    /**
     * A ProjectInfo-derived object for the older version of the project
     */
    private ProjectInfo oldProject = null;

    /**
     * Used to store the child element named "old", which is under the 
     * JDiff task XML element.
     */
    public void addConfiguredOld(ProjectInfo projInfo) {
	oldProject = projInfo;
    }

    /**
     * A ProjectInfo-derived object for the newer version of the project
     */
    private ProjectInfo newProject = null;

    /**
     * Used to store the child element named "new", which is under the 
     * JDiff task XML element.
     */
    public void addConfiguredNew(ProjectInfo projInfo) {
	newProject = projInfo;
    }

    /**
     * This class handles the information about a project, whether it is
     * the older or newer version.
     *
     * Note: Don't confuse this class with the Project used by Ant.
     * This ProjectInfo class is from local to this task.
     */
    public static class ProjectInfo {
	/** 
	 * The name of the project. This is used (without spaces) as the 
	 * base of the name of the file which contains the XML representing 
	 * the project.
	 */
	private String name;

	public void setName(String value) {
	    name = value;
	}

	public String getName() {
	    return name;
	}

	/** 
	 * The location of the Javadoc HTML for this project. Default value
	 * is "generate", which will cause the Javadoc to be generated in 
	 * a subdirectory named "name" in the task's destdir directory.
	 */
	private String javadoc;

	public void setJavadoc(String value) {
	    javadoc = value;
	}

	public String getJavadoc() {
	    return javadoc;
	}

 	/**
	 * These are the directories which contain the packages which make 
	 * up the project. Filesets are not supported by JDiff.
	 */
	private Vector dirsets = new Vector();

	public void setDirset(DirSet value) {
	    dirsets.add(value);
	}

	public Vector getDirsets() {
	    return dirsets;
	}

	/** 
	 * Used to store the child element named "dirset", which is under the 
	 * "old" or "new" XML elements.
	 */
	public void addDirset(DirSet aDirset) {
	    setDirset(aDirset);
	}
	
    }
}
