package org.eclipse.wst.jsdt.core.tools.comparators;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

public final class DirectoryComparator {

	private static void collectAllFiles(File root, ArrayList collector) {
		File[] files = root.listFiles();for (int i = 0; i < files.length; i++) {
			final File currentFile = files[i];if (currentFile.isDirectory()) {
				collectAllFiles(currentFile, collector);
			} else {
				collector.add(currentFile);
			}
		}
	}

	private static File[] getAllFiles(File root) {
		ArrayList files = new ArrayList();
		if (root.isDirectory()) {
			collectAllFiles(root, files);
			File[] result = new File[files.size()];
			files.toArray(result);
			return result;
		} else {
			return null;
		}
	}
	public static void main(String[] args) {
		if (args.length != 3) {
			System.out.println("Usage: firstDirectory secondDirectory logFile");
			return;
		}
		new DirectoryComparator(args).compare();
	}

	private boolean abortComparison;

	private File firstDirectory;

	private File resultFile;

	private File secondDirectory;
	
	private Writer writer;

	private static final int DEFAULT_READING_SIZE = 8192;

	public DirectoryComparator(String[] args) {
		this.firstDirectory = new File(args[0]);
		this.secondDirectory = new File(args[1]);
		this.resultFile = new File(args[2]);
		this.abortComparison = false;
		if (!firstDirectory.isDirectory()) {
			System.out.println("The first argument has to be a directory");
			this.abortComparison = true;
		}
		if (!secondDirectory.isDirectory()) {
			System.out.println("The second argument has to be a directory");
			this.abortComparison = true;
		}
		if (resultFile.isDirectory()) {
			System.out.println("The third argument has to be a file");
			this.abortComparison = true;
		}
	}

	public void compare() {
		if (this.abortComparison) {
			return;
		}
		File[] files = getAllFiles(firstDirectory);
		if (files == null) {
			return;
		}
		File[] secondFiles = getAllFiles(secondDirectory);
		if (secondFiles == null) {
			return;
		}
		final String firstDirectoryAbsolutePath = firstDirectory.getAbsolutePath();
		final String secondDirectoryAbsolutePath = secondDirectory.getAbsolutePath();
		if (resultFile.exists()) {
			if (!resultFile.delete()) {
				System.out.println("Could not delete " + resultFile);
				return;
			}
		}
		if (secondFiles.length != files.length) {
			final String errorMessage = "Different number of jars files:\n" +
				"\t" + secondFiles.length + " in " + secondDirectoryAbsolutePath + "\n" +
				"\t" + files.length + " in " + firstDirectoryAbsolutePath + "\n";
			logError(errorMessage);
		}
		for (int i = 0, max = files.length; i < max; i++) {
			String currentFile = files[i].getAbsolutePath();
			String firstFileName = currentFile;
			// extract the second file name
			String secondFileName = secondDirectoryAbsolutePath + File.separator + currentFile.substring(firstDirectoryAbsolutePath.length() + 1);
			if (new File(secondFileName).exists()) {
				if (firstFileName.toLowerCase().endsWith(".jar")) {
					new JarFileComparator(new String[]{firstFileName, secondFileName,
							resultFile.getAbsolutePath()}).compare();
				} else {
					// do a binary compare byte per byte
					File firstFile = new File(firstFileName);
					File secondFile = new File(secondFileName);
					byte[] contentsFile1 = getBytes(firstFile);
					byte[] contentsFile2 = getBytes(secondFile);
					if (!equals(contentsFile1, contentsFile2)) {
						logError("DIFFERENT CONTENTS: " + firstFile.getName() + "\n");
					}
				}
			} else {
				logError(secondFileName + " doesn't exist");
			}
		}
		System.out.println("DONE. Check the file "
				+ resultFile.getAbsolutePath() + " to see the result.");
		if (this.writer != null) {
			try {
				writer.flush();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private boolean equals(byte[] contentsFile1, byte[] contentsFile2) {
		if (contentsFile1 == null) {
			return contentsFile2 == null;
		}
		if (contentsFile2 == null) return false;
		int contentsFile1Length = contentsFile1.length;
		int contentsFile2Length = contentsFile2.length;
		if (contentsFile1Length != contentsFile2Length) return false;
		for (int i = 0; i < contentsFile1Length; i++) {
			if (contentsFile1[i] != contentsFile2[i]) {
				return false;
			}
		}
		return true;
	}
	
	public byte[] getBytes(File file) {
	byte[] contents;
		try {contents = new byte[0];
			int contentsLength = 0;
			int amountRead = -1;
			FileInputStream stream = new FileInputStream(file);
			do {
				int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
				
				// resize contents if needed
				if (contentsLength + amountRequested > contents.length) {
					System.arraycopy(
						contents,
						0,
						contents = new byte[contentsLength + amountRequested],
						0,
						contentsLength);
				}

				// read as many bytes as possible
				amountRead = stream.read(contents, contentsLength, amountRequested);

				if (amountRead > 0) {
					// remember length of contents
					contentsLength += amountRead;
				}
			} while (amountRead != -1); 

			// resize contents if necessary
			if (contentsLength < contents.length) {
				System.arraycopy(
					contents,
					0,
					contents = new byte[contentsLength],
					0,
					contentsLength);
			}
return contents;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
		e.printStackTrace();
}
	return null;
}
	
	private void logError(String message) {
		try {
			if (this.writer == null) {
				this.writer = new BufferedWriter(new FileWriter(this.resultFile, true));
			}
			writer.write(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}