/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     
 *******************************************************************************/

package org.eclipse.callisto.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;

import org.eclipse.callisto.tools.utils.FullJarNameParser;
import org.eclipse.callisto.tools.utils.LineInfo;
import org.eclipse.callisto.tools.utils.ProjectInfoPair;
import org.eclipse.callisto.tools.utils.Version;

public class GenerateMirrorTags {

	private FullJarNameParser jarNameParser = new FullJarNameParser();

	private static final String QUOTE = "\""; //$NON-NLS-1$

	private static final String ARCHIVE_PATH = "<archive path="; //$NON-NLS-1$

	private static final String SLASH = "/"; //$NON-NLS-1$

	private static final char CHAR_BASKSLASH = '\\';

	private static final char CHAR_SLASH = '/';

	private static final String PLUGINS = "plugins"; //$NON-NLS-1$

	private static final String FEATURES = "features"; //$NON-NLS-1$

	private static final String IGNORE = "/home/data/httpd/download.eclipse.org/"; //$NON-NLS-1$

	private static final boolean DEBUG = false;

	private static final String urlCONST = " url=\""; //$NON-NLS-1$

	private static final String nearestMirrorURL = "http://www.eclipse.org/downloads/download.php?r=1&amp;file=/"; //$NON-NLS-1$

	private static final String relativeURL = "../../"; //$NON-NLS-1$

	private static final String ENDTAG = "/>"; //$NON-NLS-1$

	private static final String EOL = System.getProperty("line.separator"); //$NON-NLS-1$

	static final String PATH_SEPARATOR = System.getProperty("path.separator"); //$NON-NLS-1$

	private static final String DATADIR = "data"; //$NON-NLS-1$

	private static final boolean VERBOSE = true;

	private Hashtable pluginTable = new Hashtable();

	private Hashtable featureTable = new Hashtable();

	private ArrayList featureList = new ArrayList();

	private ArrayList pluginList = new ArrayList();

	public static void main(String[] args) {

		System.out.println();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
		System.out.println("\t" + dateFormat.format(new Date())); //$NON-NLS-1$
		System.out.println();

		System.out.println("\tSystem Properties for some interesting locations"); //$NON-NLS-1$
		System.out.println();
		System.out.println("\t\tuser.dir: \t\t" + System.getProperty("user.dir")); //$NON-NLS-1$ //$NON-NLS-2$
		System.out.println("\t\tuser.home: \t\t" + System.getProperty("user.home")); //$NON-NLS-1$ //$NON-NLS-2$
		System.out.println("\t\tjava.io.tmpdir: \t" + System.getProperty("java.io.tmpdir")); //$NON-NLS-1$ //$NON-NLS-2$
		System.out.println();
		System.out.println();

		try {

			String propertyFileName = null;
			String[] filenames = null;

			if (args.length == 0) {
				propertyFileName = new String("updateDirs.properties"); //$NON-NLS-1$
				Properties updateDirectories = new Properties();

				String userDirectory = System.getProperty("user.dir"); //$NON-NLS-1$
				File propertyDir = new File(userDirectory);
				File file = new File(propertyDir, propertyFileName);
				InputStream inProperties = null;
				String propertiesSource = null;
				if (file.exists()) {
					inProperties = new FileInputStream(file);
					propertiesSource = file.getAbsolutePath();
				}
				else {
					inProperties = GenerateMirrorTags.class.getClassLoader().getResourceAsStream(propertyFileName);
					propertiesSource = "jar: " + propertyFileName; //$NON-NLS-1$
				}

				System.out.println("\tUsing properties from " + EOL + "\t\t" + propertiesSource); //$NON-NLS-1$ //$NON-NLS-2$
				updateDirectories.load(inProperties);


				filenames = initFileNamesFromProperties(updateDirectories);

			}
			else {
				filenames = args;
			}
			new GenerateMirrorTags().generateFromPathNames(filenames);


		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static String[] initFileNamesFromProperties(Properties updateDirectories) {
		String[] result = new String[0];
		ArrayList nameProperties = new ArrayList();
		Enumeration allProperties = updateDirectories.keys();
		while (allProperties.hasMoreElements()) {
			String propertyname = (String) allProperties.nextElement();
			String dirname = null;
			if (propertyname.startsWith("updateDir")) { //$NON-NLS-1$
				dirname = updateDirectories.getProperty(propertyname);
				nameProperties.add(dirname);
			}
		}
		if (nameProperties.size() > 0) {
			result = new String[nameProperties.size()];
			for (int iProp = 0; iProp < nameProperties.size(); iProp++) {
				result[iProp] = (String) nameProperties.get(iProp);
			}
		}
		return result;
	}

	private int totalTags;

	private String UNDERSCORE = "_"; //$NON-NLS-1$

	private boolean doNearestMirror = false;

	private boolean doRelativeURL = true;

	private void generateFromPathNames(String[] pathnames) throws IOException {

		int nPathNames = pathnames.length;
		System.out.println();
		System.out.print("\tTotal PathNames to be processed: " + nPathNames); //$NON-NLS-1$
		System.out.println();

		for (int iPath = 0; iPath < nPathNames; iPath++) {
			String pathname = pathnames[iPath];

			File mainDirectory = new File(pathname);
			if (!mainDirectory.exists()) {
				System.out.println("\n\tSkipping a path from property file, that did not exist: " + mainDirectory); //$NON-NLS-1$
			}
			else {
				if (!mainDirectory.isDirectory()) {
					System.err.println("We expect to get directory names as the input."); //$NON-NLS-1$
				}
				else {

					pluginTable.clear();
					featureTable.clear();
					featureList.clear();
					pluginList.clear();

					String[] members = mainDirectory.list();

					for (int jMember = 0; jMember < members.length; jMember++) {

						String member = members[jMember];

						if (DEBUG) {
							System.out.println(member);
						}

						if (FEATURES.equals(member)) {
							File featureDirectory = new File(mainDirectory, member);
							String[] featureNames = featureDirectory.list();

							for (int iFeatureName = 0; iFeatureName < featureNames.length; iFeatureName++) {
								String featureName = featureNames[iFeatureName];

								if (DEBUG) {
									System.out.println(featureName);
								}

								jarNameParser.parse(featureName);
								String projectId = jarNameParser.getProjectString();
								String versionString = jarNameParser.getVersionString();
								Version version = createVersionFromString(featureName, projectId, versionString);
								if (version != null) {
									storeInTable(featureTable, projectId, version, featureDirectory + SLASH + featureName);
									storeInList(featureList, projectId, version, featureDirectory + SLASH + featureName);
								}
							}
						}
						else if (PLUGINS.equals(member)) {
							File pluginDirectory = new File(mainDirectory, member);
							String[] pluginNames = pluginDirectory.list();

							for (int iPluginName = 0; iPluginName < pluginNames.length; iPluginName++) {
								String pluginName = pluginNames[iPluginName];

								if (DEBUG) {
									System.out.println(pluginName);
								}

								jarNameParser.parse(pluginName);
								String projectId = jarNameParser.getProjectString();
								String versionString = jarNameParser.getVersionString();
								Version version = createVersionFromString(pluginName, projectId, versionString);
								if (version != null) {
									storeInTable(pluginTable, projectId, version, pluginDirectory + SLASH + pluginName);
									storeInList(pluginList, projectId, version, pluginDirectory + SLASH + pluginName);
								}
							}
						}

					}

					String newFileName = newFileName(pathname);

					createTagFileMR(newFileName + "-MR"); //$NON-NLS-1$
					createTagFileALL(newFileName + "-All"); //$NON-NLS-1$

				}

			}
		}

	}

	private Version createVersionFromString(String wholeName, String projectId, String versionString) {
		Version result = null;
		try {
			result = new Version(versionString);
		}
		catch (NumberFormatException e) {
			System.out.println();
			System.out.println(" Number Format Exception creating Version"); //$NON-NLS-1$
			System.out.println("featureName: " + wholeName); //$NON-NLS-1$
			System.out.println("projectId: " + projectId); //$NON-NLS-1$
			System.out.println("versionString: " + versionString); //$NON-NLS-1$
			System.out.println();
		}
		return result;
	}

	private void createTagFileMR(String filename) throws IOException {

		File dataDir = ensureDataDirectory();

		File file = new File(dataDir, filename);
		FileWriter writer = new FileWriter(file);

		Enumeration features = featureTable.keys();
		while (features.hasMoreElements()) {
			String id = (String) features.nextElement();
			LineInfo lineInfo = (LineInfo) featureTable.get(id);
			createTag(writer, id, FEATURES, lineInfo.getLine());
		}

		Enumeration plugins = pluginTable.keys();
		while (plugins.hasMoreElements()) {
			String id = (String) plugins.nextElement();
			LineInfo lineInfo = (LineInfo) pluginTable.get(id);
			createTag(writer, id, PLUGINS, lineInfo.getLine());
		}
		writer.close();

		printSummary(filename, featureTable.size(), pluginTable.size());
	}

	private void printSummary(String filename, int nFeatures, int nPlugins) {
		if (VERBOSE) {
			System.out.println();
			System.out.println("\t\t" + filename); //$NON-NLS-1$
			System.out.println("\t\t\t" + "number of features: " + nFeatures); //$NON-NLS-1$ //$NON-NLS-2$
			System.out.println("\t\t\t" + " number of plugins: " + nPlugins); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void createTagFileALL(String filename) throws IOException {

		File dataDir = ensureDataDirectory();

		File file = new File(dataDir, filename);
		FileWriter writer = new FileWriter(file);

		Iterator features = featureList.iterator();
		writeTags(writer, features, FEATURES);

		Iterator plugins = pluginList.iterator();
		writeTags(writer, plugins, PLUGINS);

		writer.close();

		printSummary(filename, featureList.size(), pluginList.size());

	}

	private File ensureDataDirectory() throws IOException {
		String writeDirectory = System.getProperty("user.dir"); //$NON-NLS-1$
		File writeDir = new File(writeDirectory);
		File dataDir = new File(writeDir, DATADIR);
		if (!dataDir.exists()) {
			boolean success = dataDir.mkdirs();
			if (!success) {
				throw new IOException("Could not create directory: " + dataDir.getName()); //$NON-NLS-1$
			}
		}
		return dataDir;
	}

	private void writeTags(FileWriter writer, Iterator iterator, String type) throws IOException {
		while (iterator.hasNext()) {
			ProjectInfoPair info = (ProjectInfoPair) iterator.next();
			String id = info.getProjectId();
			LineInfo lineInfo = info.getLineInfo();
			createTag(writer, id, type, lineInfo.getLine());
		}
	}

	private String newFileName(String filename) {
		// System.out.println("pathname processed: " + filename);
		String name = filename;
		if (name.startsWith(IGNORE)) {
			name = name.substring(IGNORE.length());
		}
		name = name.replace(CHAR_SLASH, '-');
		name = name.replace(CHAR_BASKSLASH, '-');
		if (name.startsWith("-")) { //$NON-NLS-1$
			name = name.substring(1);
		}
		if (!name.endsWith("-")) { //$NON-NLS-1$
			name = name + "-"; //$NON-NLS-1$
		}
		name = name + "Tags" + "." + "xmlinc"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		// System.out.println("filename created: " + name);
		return name;
	}

	private void storeInTable(Hashtable table, String projectId, Version version, String lineParam) {

		String lineToStore = lineParam.replace(CHAR_BASKSLASH, CHAR_SLASH);
		if (lineToStore.startsWith(IGNORE)) {
			lineToStore = lineToStore.substring(IGNORE.length());
		}

		if (notInSkipList(lineToStore)) {
			// if see if project in table at all, if not store it. If so,
			// update
			// version and line, if higher.
			Object data = table.get(projectId);
			if (data == null) {
				LineInfo lineInfo = new LineInfo(version, lineToStore);
				table.put(projectId, lineInfo);
			}
			else {
				LineInfo lineinfo = (LineInfo) data;
				Version currentVersion = lineinfo.getVersion();
				if (version.compareTo(currentVersion) > 0) {
					LineInfo newlineInfo = new LineInfo(version, lineToStore);
					table.put(projectId, newlineInfo);
					if (DEBUG) {
						System.out.println("\tVersion Replaced: " + projectId); //$NON-NLS-1$
						System.out.println("\t\t" + version + " greater then " + currentVersion); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
			}
		}

	}

	private void storeInList(ArrayList list, String projectId, Version version, String lineParam) {

		String lineToStore = lineParam.replace(CHAR_BASKSLASH, CHAR_SLASH);
		if (lineToStore.startsWith(IGNORE)) {
			lineToStore = lineToStore.substring(IGNORE.length());
		}

		if (notInSkipList(lineToStore)) {
			LineInfo newlineInfo = new LineInfo(version, lineToStore);
			ProjectInfoPair projectInfoPair = new ProjectInfoPair(projectId, newlineInfo);
			list.add(projectInfoPair);
		}

	}

	private boolean notInSkipList(String directory) {
		boolean result = false;
		if (directory != null && directory.length() > 0) {
			if (contains(directory, ".tests_") || contains(directory, ".tests.") || contains(directory, "validation.test") || contains(directory, "validation.sample") || contains(directory, "tests.feature")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
				result = false;
			}
			else {
				result = true;
			}
		}
		return result;
	}

	private boolean contains(String directory, String string) {
		return (-1 < directory.indexOf(string));
	}

	private void createTag(Writer writer, String directory, String type, String line) throws IOException {
		jarNameParser.parse(line);
		String versionString = jarNameParser.getVersionString();
		String tagStart = ARCHIVE_PATH + QUOTE + type + SLASH + directory + UNDERSCORE + versionString + ".jar" + QUOTE; //$NON-NLS-1$

		String urlAttrib = null;
		String avoidDoubleSlashLine = line;
		if (avoidDoubleSlashLine.startsWith(SLASH)) {
			avoidDoubleSlashLine = avoidDoubleSlashLine.substring(1);
		}
		if (doNearestMirror) {
			urlAttrib = urlCONST + nearestMirrorURL + avoidDoubleSlashLine + QUOTE + ENDTAG;
		}
		else if (doRelativeURL) {
			urlAttrib = urlCONST + relativeURL + avoidDoubleSlashLine + QUOTE + ENDTAG;
		}
		else {
			throw new IllegalStateException("url type is not specified correctly"); //$NON-NLS-1$
		}

		writer.write(EOL);
		writer.write("\t" + tagStart + EOL); //$NON-NLS-1$
		writer.write("\t\t" + urlAttrib + EOL); //$NON-NLS-1$
		writer.write(EOL);
		writer.flush();

		totalTags++;

	}
}
