/**
 * @Contributors:<A HREF="mailto:sebastien.chassande@inrialpes.fr>
 * <b>S. Chassande-Barrioz</b></A>
 */

package org.objectweb.util.ant;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.taskdefs.Javadoc;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.FileWriter;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Enumeration;

/**
 * This class permits to specify on a javadoc a list of link in only one
 * parameter. The element separator is the comma.
 */
public class JavadocMultipleLink
	extends Javadoc {

	public final static String PACKAGE_HTML_FILE_NAME = "package.html";
	public final static String TEMP_CLASS_NAME = "Temp";



	private Path sourcePath = null;

	/**
	 * This parameter permits to specify a list of url (seprator = comma)
	 * This url could on line.
	 */
	public void setLinks(String d) {
		StringTokenizer st = new StringTokenizer(d, ",");
		while (st.hasMoreTokens()) {
			Javadoc.LinkArgument la = createLink();
			la.setHref((String) st.nextToken());
		}
	}
	public void setSourcepath(Path src) {
		if (sourcePath == null) {
            sourcePath = src;
        } else {
            sourcePath.append(src);
        }
		super.setSourcepath(src);
	}

	public void execute() throws BuildException {
		Vector v = new Vector();

		// Search empty package with a package.html file
		String[] paths = sourcePath.list();
		for(int i=0; i<paths.length; i++) {
			FileSet fs = new FileSet();
			fs.setProject(getProject());
			fs.setIncludes("**/*");
			fs.setDir(new File(paths[i]));
			fs.setDefaultexcludes(true);
			String[] dirs = DirectoryScannerHelper.getSelectedFilesAsString(
			        fs.getDirectoryScanner(getProject()), getProject());
			for (int j = 0; j < dirs.length; j++) {
				try {
					if (containsOnlyOneFile(
							new File(paths[i],dirs[j]),
							PACKAGE_HTML_FILE_NAME
						)) {
						v.add(new File(paths[i],dirs[j]));
					}
				}
				catch (IOException ioe) {
					System.out.println(ioe.getMessage());
				}
			}
		}

		// Add files
		try {
			for(Enumeration enu = v.elements(); enu.hasMoreElements();) {
				File current = new File((File) enu.nextElement(),
					TEMP_CLASS_NAME + ".java");
				if (!current.createNewFile())
					continue;
				FileWriter fw = new FileWriter(current);
				fw.write("class " + TEMP_CLASS_NAME + "{}");
				fw.flush();
				fw.close();
			}
		}
		catch (IOException e) {
		}

		// Execute the javadoc command
		super.execute();

		// Remove files
		for(Enumeration enu = v.elements(); enu.hasMoreElements();) {
			new File((File) enu.nextElement(),
				TEMP_CLASS_NAME + ".java").delete();
		}
	}

	public boolean containsOnlyOneFile(File dirfile, String filename)
		throws IOException {
		if (!dirfile.isDirectory())
			throw new IOException(dirfile + " is not a directory");
		// Search the directory which contains a file with the specified
		// filename
		File[] packfiles =
			dirfile.listFiles(new FileFilter(filename));
		if (packfiles != null && packfiles.length > 0) {
			// for each found directory searches if contains java source file
			for (int i=0; i<packfiles.length; i++) {
				File[] res = packfiles[i].getParentFile().listFiles(new FileFilter(".java"));
				if ( res==null || res.length==0) {
					return true;
				}
			}
		}
		return false;
	}

	class FileFilter implements FilenameFilter {

		String filter = null;

		public FileFilter(String f) {
			filter = f;
		}

		// IMPLEMENTATION OF FilenameFilter //
		//----------------------------------//

		/**
		 * Tests if a specified file should be included in a file list.
		 *
		 * @param   dir    the directory in which the file was found.
		 * @param   name   the name of the file.
		 * @return  <code>true</code> if and only if the name should be
		 * included in the file list; <code>false</code> otherwise.
		 */
		public boolean accept(File dir, String name) {
			return name.endsWith(filter);
		}
	}
}
