package org.eclipse.swt.tools.internal;

import java.io.*;
import java.util.*;

import org.eclipse.jdt.core.dom.*;
import org.eclipse.jface.text.*;

/**
 * Bashes the javadoc from one source tree into another. Only produces new
 * source files for compilation units that have changed.
 * 
 * How to use: 1) make sure you have the latest org.eclipse.swt (master branch)
 * in your workspace, and that you have no outstanding org.eclipse.swt changes
 * 2) create a Bugzilla bug called
 * "Do the annual javadoc/copyright bash for x.x" 3) make a version (tag) of the
 * org.eclipse.swt project before you bash here is a sample tag name:
 * BEFORE_JAVADOC_BASH_FOR_43RC3 use the Bugzilla bug for the tag comment 4)
 * modify the code in main, below, so that 'workspaceDir' and 'outputDir' point
 * to the (git) directory that contains org.eclipse.swt in your workspace,
 * typically C:/git/eclipse.platform.swt/bundles (prior to 3.8/4.2, these
 * pointed to the workspace directory) 5) make sure 'sourceSubdir' (usually
 * win32), 'targetSubdirs' (all others), and 'folders' are correct (note: there
 * are typically a few new targetSubdirs and folders every year... although
 * nothing new for 4.3) 6) run JavadocBasher (for a more verbose output, set
 * fVerbose to true) 7) refresh (F5) the org.eclipse.swt project inside eclipse
 * 8) search for *** in console output to see results of API consistency
 * checking 9) synchronize, carefully reviewing every change. Watch out for: -
 * duplicated comments - // comments that have been removed (if they appear
 * before a javadoc comment) 10) use the Bugzilla bug as the commit comment for
 * javadoc and copyright bash commits 11) make a version of the org.eclipse.swt
 * project after bashing (use tag name AFTER_...)
 * 
 * 12) Copyright bash (tag before and after): NOTE: JavadocBasher does not fix
 * copyrights. Use the "Fix Copyrights" tool in org.eclipse.releng.tools for
 * that (always fix copyrights after bash). Use Help->Install New Software... to
 * install "Releng Tools" from the "Eclipse Project Updates" site (for release -
 * 1). Select org.eclipse.swt project and choose "Fix Copyrights" from the
 * context menu. See http://wiki.eclipse.org/Development_Resources/
 * How_to_Use_Eclipse_Copyright_Tool for more info. NOTE: The copyright tool
 * takes about 45 minutes to run (for SWT). NOTE 2: Check console for possible
 * errors/warnings, refresh (F5), synchronize, and browse all changes. Use
 * keyboard (Ctrl+.) for next diff instead of mouse (keyboard is faster because
 * there are fewer focus changes). Only use git History view as needed - if it
 * is open and linked with editor, it gets bogged down and lags behind. NOTE 3:
 * SWT anomalies that confuse the tool: - Some ns*.h files in
 * Mozilla/common/library do not contain the word "copyright" so the tool tries
 * to add one - don't keep it (the text is fine as-is). - Other ns*.h files in
 * Mozilla/common/library have a copyright line that should not be updated
 * (Initial Developer) - don't keep the change suggested by the tool (the text
 * is fine as-is). - The ns*.java and some other *.java files in
 * internal/mozilla have 2 copyright lines and the tool tries to change the 1st
 * - don't keep the 1st change (Netscape 1998-1999), but update the 2nd (IBM)
 * manually.
 * 
 * NOTE: JavadocBasher now does a fairly good job of checking API consistency.
 * We used to use org.eclipse.swt.diff for API consistency checking, but it was
 * difficult to maintain.
 */
public class JavadocBasher {
	static final boolean fVerbose = false; // set to true for verbose output
	List<String> fBashed;
	List<String> fUnchanged;
	List<String> fSkipped;

	public JavadocBasher() {
		fBashed = new ArrayList<String>();
		fUnchanged = new ArrayList<String>();
		fSkipped = new ArrayList<String>();
	}
	
	public static class Edit {
		int start, length;
		String text;

		public Edit(int start, int length, String text) {
			this.start = start;
			this.length = length;
			this.text = text;
		}
	}

	public static void main(String[] args) {
		String workspaceDir = ".."; // use forward slashes, no final slash
		String outputDir = ".."; // can point to another directory for debugging
		String[] folders = new String[] { // commented folders do not need to be
				// bashed
				"Eclipse SWT", "Eclipse SWT Accessibility",
				"Eclipse SWT AWT",
				"Eclipse SWT Browser",
				// "Eclipse SWT Custom Widgets",
				"Eclipse SWT Drag and Drop", "Eclipse SWT Effects",
				"Eclipse SWT Mozilla",
				// "Eclipse SWT OLE Win32",
				"Eclipse SWT OpenGL",
				// "Eclipse SWT PI",
				"Eclipse SWT Printing", "Eclipse SWT Program",
				"Eclipse SWT Theme", "Eclipse SWT WebKit", };
		String sourceSubdir = "win32";
		String[] targetSubdirs = new String[] { "cairo", // used by gtk
				// "carbon", // we are no longer maintaining carbon
				"cde", // used by gtk
				"cocoa",
				// "common",
				// "common_j2me",
				// "common_j2se",
				"emulated", "emulated/bidi", // used by carbon, cocoa
				"emulated/coolbar", // used by carbon, cocoa, gtk
				"emulated/expand", // used by carbon, cocoa
				"emulated/taskbar", // used by carbon, gtk
				"emulated/tooltip", // used by cocoa (?!)
				"gnome", // used by gtk
				"glx", // used by gtk
				"gtk",
				"mozilla", // used by carbon, cocoa, gtk, win32
		// "qt", // folder should be deleted
		};

		System.out.println("==== Start Bashing ====");
		int totalBashed = 0;
		for (int t = 0; t < targetSubdirs.length; t++) {
			for (int f = 0; f < folders.length; f++) {
				String targetSubdir = folders[f] + "/" + targetSubdirs[t];
				File source = new File(workspaceDir + "/org.eclipse.swt/"
						+ folders[f] + "/" + sourceSubdir);
				File target = new File(workspaceDir + "/org.eclipse.swt/"
						+ targetSubdir);
				File out = new File(outputDir + "/org.eclipse.swt/"
						+ targetSubdir);
				JavadocBasher basher = new JavadocBasher();
				System.out.println("\n==== Start Bashing " + targetSubdir);
				basher.bashJavaSourceTree(source, target, out);
				List<String> bashedList = basher.getBashed();
				basher.status("Bashed", bashedList, targetSubdir);
				if (bashedList.size() > 0) {
					totalBashed += bashedList.size();
					if (fVerbose)
						basher.status("Didn't change", basher.getUnchanged(),
								targetSubdir);
					basher.status("Skipped", basher.getSkipped(), targetSubdir);
				}
				System.out.println("==== Done Bashing " + targetSubdir);
			}
		}
		System.out.println("\n==== Done Bashing (Bashed " + totalBashed
				+ " files in total) - Be sure to Refresh (F5) project(s) ====");
	}

	void status(String label, List<String> list, String targetSubdir) {
		int count = list.size();
		System.out.println(label + " " + count
				+ ((count == 1) ? " file" : " files") + " in " + targetSubdir
				+ ((count > 0) ? ":" : "."));
		if (count > 0) {
			Iterator<String> i = list.iterator();
			while (i.hasNext())
				System.out.println(label + ": " + i.next());
			System.out.println();
		}
	}

	char[] readFile(File file) {
		try {
			Reader in = new FileReader(file);
			CharArrayWriter storage = new CharArrayWriter();
			char[] chars = new char[8192];
			int read = in.read(chars);
			while (read > 0) {
				storage.write(chars, 0, read);
				storage.flush();
				read = in.read(chars);
			}
			in.close();
			return storage.toCharArray();
		} catch (IOException ioe) {
			System.out.println("*** Could not read " + file);
		}
		return null;
	}

	void writeFile(char[] contents, File file) {
		try {
			Writer out = new FileWriter(file);
			out.write(contents);
			out.flush();
			out.close();
		} catch (IOException ioe) {
			System.out.println("*** Could not write to " + file);
			if (fVerbose) {
				System.out.println("<dump filename=\"" + file + "\">");
				System.out.println(contents);
				System.out.println("</dump>");
			}
		}
	}

	void bashJavaSourceTree(File sourceDir, File targetDir, File outDir) {
		if (fVerbose)
			System.out.println("Reading source javadoc from " + sourceDir);
		if (!sourceDir.exists()) {
			System.out.println("Source: " + sourceDir + " was missing");
			return;
		}
		if (!targetDir.exists()) {
			System.out.println("Target: " + targetDir + " was missing");
			return;
		}

		String[] list = sourceDir.list();
		if (list != null) {
			int count = list.length;
			for (int i = 0; i < count; i++) {
				String filename = list[i];
				if (filename.equals("CVS") || filename.equals("internal")
						|| filename.equals("library"))
					continue;
				File source = new File(sourceDir, filename);
				File target = new File(targetDir, filename);
				File out = new File(outDir, filename);
				if (source.exists() && target.exists()) {
					if (source.isDirectory()) {
						if (target.isDirectory()) {
							bashJavaSourceTree(source, target, out);
						} else {
							System.out.println("*** " + target
									+ " should have been a directory.");
						}
					} else {
						if (filename.toLowerCase().endsWith(".java")) {
							bashFile(source, target, out);
						} else {
							fSkipped.add(source + " (not a java file)");
						}
					}
				} else {
					if (source.exists()) {
						fSkipped.add(target + " (does not exist)");
					} else {
						fSkipped.add(source + " (does not exist)");
					}
				}
			}
		}
	}


	void bashFile(final File source, final File target, File out) {
		char[] contents = readFile(source);
		if (contents == null) return;
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		final Document sourceDocument = new Document(new String(contents));
		parser.setSource(contents);
		CompilationUnit sourceUnit = (CompilationUnit)parser.createAST(null);

		contents = readFile(target);
		if (contents == null) return;
		String targetContents = new String(contents);
		final Document targetDocument = new Document(targetContents);
		parser.setSource(contents);
		CompilationUnit targetUnit = (CompilationUnit)parser.createAST(null);

		final HashMap<String, String> comments = new HashMap<String, String>();
		sourceUnit.accept(new ASTVisitor() {
			String prefix = "";
			@Override
			public boolean visit(Block node) {
				return false;
			}
			@Override
			public boolean visit(VariableDeclarationFragment node) {
				FieldDeclaration field = (FieldDeclaration)node.getParent();
				int mods = field.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = field.getJavadoc();
					if (field.fragments().size() > 1 && javadoc != null) {
						System.err.println("Field declaration with multiple variables is not supported. -> " + source + " " + node.getName().getFullyQualifiedName());
					}
					try {
						String key = prefix + "." + node.getName().getFullyQualifiedName();
						comments.put(key, javadoc != null ? sourceDocument.get(javadoc.getStartPosition(), getJavadocLength(sourceDocument, javadoc)) : "");
					} catch (BadLocationException e) {}
					return true;
				}
				return false;
			}
			@Override
			public boolean visit(MethodDeclaration node) {
				int mods = node.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = node.getJavadoc();
					try {
						String key = prefix + "." + node.getName().getFullyQualifiedName();
						for (Iterator<SingleVariableDeclaration> iterator = node.parameters().iterator(); iterator.hasNext();) {
							SingleVariableDeclaration param = iterator.next();
							key += param.getType().toString();
						}
						comments.put(key, javadoc != null ? sourceDocument.get(javadoc.getStartPosition(), getJavadocLength(sourceDocument, javadoc)) : "");
					} catch (BadLocationException e) {}
					return true;
				}
				return false;
			}
			@Override
			public boolean visit(TypeDeclaration node) {
				int mods = node.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = node.getJavadoc();
					try {
						String key = prefix + "." + node.getName().getFullyQualifiedName();
						comments.put(key, javadoc != null ? sourceDocument.get(javadoc.getStartPosition(), getJavadocLength(sourceDocument, javadoc)) : "");
					} catch (BadLocationException e) {}
					prefix = node.getName().getFullyQualifiedName();
					return true;
				}
				return false;
			}
		});


		final List<Edit> edits = new ArrayList<Edit>();
		targetUnit.accept(new ASTVisitor() {
			String prefix = "";
			@Override
			public boolean visit(Block node) {
				return false;
			}
			@Override
			public boolean visit(VariableDeclarationFragment node) {
				FieldDeclaration field = (FieldDeclaration)node.getParent();
				int mods = field.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = field.getJavadoc();
					if (field.fragments().size() > 1 && javadoc != null) {
						System.err.println("Field declaration with multiple variables is not supported. -> " + target + " " + node.getName().getFullyQualifiedName());
					}
					String key = prefix + "." + node.getName().getFullyQualifiedName();
					String newComment = comments.get(key);
					if (newComment != null) {
						comments.remove(key);
						if (javadoc != null) {
							edits.add(new Edit(javadoc.getStartPosition(), getJavadocLength(targetDocument, javadoc), newComment));
						} else {
							edits.add(new Edit(field.getStartPosition(), 0, newComment));
						}
					}
					return true;
				}
				return false;
			}
			@Override
			public boolean visit(MethodDeclaration node) {
				int mods = node.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = node.getJavadoc();
					String key = prefix + "." + node.getName().getFullyQualifiedName();
					for (Iterator<SingleVariableDeclaration> iterator = node.parameters().iterator(); iterator.hasNext();) {
						SingleVariableDeclaration param = iterator.next();
						key += param.getType().toString();
					}
					String newComment = comments.get(key);
					if (newComment != null) {
						comments.remove(key);
						if (javadoc != null) {
							edits.add(new Edit(javadoc.getStartPosition(), getJavadocLength(targetDocument, javadoc), newComment));
						} else {
							edits.add(new Edit(node.getStartPosition(), 0, newComment));
						}
					}
					return true;
				}
				return false;
			}
			@Override
			public boolean visit(TypeDeclaration node) {
				int mods = node.getModifiers();
				if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
					Javadoc javadoc = node.getJavadoc();
					String key = prefix + "." + node.getName().getFullyQualifiedName();
					String newComment = comments.get(key);
					if (newComment != null) {
						comments.remove(key);
						if (javadoc != null) {
							edits.add(new Edit(javadoc.getStartPosition(), getJavadocLength(targetDocument, javadoc), newComment));
						} else {
							edits.add(new Edit(node.getStartPosition(), 0, newComment));
						}
					}
					prefix = node.getName().getFullyQualifiedName();
					return true;
				}
				return false;
			}
		});

		for (int i = edits.size() - 1; i >=0 ; i--) {
			Edit edit = edits.get(i);
			try {
				targetDocument.replace(edit.start, edit.length, edit.text);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}
		/* Rudimentary API consistency checker.
		 * This assumes that:
		 * a) the sourceSubdir (typically win32) API is correct
		 * b) all sourceSubdir API classes, methods and fields do have a comment
		 * c) names that are in the filter list are never API,
		 * 		or they are old API that is defined in the super on some platforms
		 */
		if (comments.size() > 0) {
			String [] filter = new String [] {
				"Color.win32_newDeviceint",
				"Cursor.win32_newDeviceint",
				"Device.hPalette",
				"Font.win32_newDevicelong",
				"FontData.data",
				"FontData.win32_newLOGFONTfloat",
				"FontMetrics.handle",
				"FontMetrics.win32_newTEXTMETRIC",
				"GC.win32_newlongGCData",
				"GC.win32_newDrawableGCData",
				"Image.win32_newDeviceintlong",
				"Pattern.handle",
				"Region.win32_newDeviceint",
				"Control.handle",
				"Display.getSystemFont",
				"Display.msg",
				"Menu.handle",
				"Shell.win32_newDisplaylong",	
				"Accessible.internal_WM_GETOBJECTlonglong",
				"TransferData.result",
				"TransferData.stgmedium",
				"TransferData.pIDataObject",
				"TransferData.formatetc",
				"Printer.handle",
				"Printer.checkDevice",	
				"TableDragSourceEffect.dragFinishedDragSourceEvent",
				"TableDragSourceEffect.dragStartDragSourceEvent",
				"TableDropTargetEffect.dragOverDropTargetEvent",
				"TableDropTargetEffect.dragEnterDropTargetEvent",
				"TableDropTargetEffect.dragLeaveDropTargetEvent",
				"Transfer.validateObject",
				"TransferData.result",
				"TransferData.stgmedium",
				"TransferData.pIDataObject",
				"TransferData.formatetc",
				"TreeDragSourceEffect.dragFinishedDragSourceEvent",
				"TreeDragSourceEffect.dragStartDragSourceEvent",
				"TreeDropTargetEffect.dragLeaveDropTargetEvent",
				"TreeDropTargetEffect.dragEnterDropTargetEvent",
				"TreeDropTargetEffect.dragOverDropTargetEvent",
				"Printer.createDeviceData",
				"Printer.internal_dispose_GClongGCData",
				"Printer.release",
				"Printer.destroy",
				"Image.handle",
				"Display.getClientArea",
				"TreeItem.handle",
			};
			for (Iterator<String> iterator = comments.keySet().iterator(); iterator.hasNext();) {
				String name = iterator.next();
				if (comments.get(name).length() > 0){
					int i = 0;
					for (i = 0; i < filter.length; i++) {
						if (name.equals(filter[i])) break;
					}
					if (i >= filter.length) {
						System.err.println("***No target for " + name);
					}
				}
			}
		}
		
		String newContents = targetDocument.get();
		if (!targetContents.equals(newContents)) {
			if (makeDirectory(out.getParentFile())) {
				writeFile(newContents.toCharArray(), out);
				fBashed.add(target.toString());
			} else {
				System.out.println("*** Could not create " + out.getParent());
			}
		} else {
			fUnchanged.add(target.toString());
		}
	}

	int getJavadocLength(Document sourceDocument, Javadoc javadoc) {
		return skipWhitespace(sourceDocument, javadoc.getStartPosition() + javadoc.getLength()) - javadoc.getStartPosition();
	}
	
	int skipWhitespace(Document doc, int offset) {
		try {
			while (Character.isWhitespace(doc.getChar(offset))){
				offset++;
			}
		} catch (BadLocationException e) {
		}
		return offset;
	}

	boolean makeDirectory(File directory) {
		if (directory.exists())
			return true;
		return directory.mkdirs();
	}

	List<String> getBashed() {
		return fBashed;
	}

	List<String> getUnchanged() {
		return fUnchanged;
	}

	List<String> getSkipped() {
		return fSkipped;
	}
}
