package org.eclipse.swt.tools.internal;

import java.io.*;
import java.util.*;
import java.util.Map.*;

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-2015), 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<>();
		fUnchanged = new ArrayList<>();
		fSkipped = new ArrayList<>();
	}
	
	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 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
				"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 (?!)
				"glx", // used by gtk
				"gtk"
		};

		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) {
			for(String s : list)
				System.out.println(label + ": " + s);
			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);
			}
			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();
		} 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<>();
		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<>();
		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 (Entry<String, String> entry: comments.entrySet()) {
				String name = entry.getKey();
				if (entry.getValue().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;
	}
}
