/*******************************************************************************
 * 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.europa.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.europa.tools.utils.FullJarNameParser;
import org.eclipse.europa.tools.utils.LineInfo;
import org.eclipse.europa.tools.utils.ProjectInfoPair;
import org.eclipse.europa.tools.utils.Version;

public class GenerateMirrorTags {

	private FullJarNameParser jarNameParser = new FullJarNameParser();

	private static final String QUOTE = "\"";

	private static final String ARCHIVE_PATH = "<archive path=";

	private static final String SLASH = "/";

	private static final char CHAR_BASKSLASH = '\\';

	private static final char CHAR_SLASH = '/';

	private static final String PLUGINS = "plugins";

	private static final String FEATURES = "features";

	private static final String IGNORE = "/home/data/httpd/download.eclipse.org/";

	private static final boolean DEBUG = false;

	private static final String urlCONST = " url=\"";

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

	private static final String relativeURL = "../../";

	private static final String ENDTAG = "/>";

	private static final String EOL = System.getProperty("line.separator");

	static final String PATH_SEPARATOR = System.getProperty("path.separator");

	private static final String DATADIR = "data";

	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()));
		System.out.println();

		System.out.println("\tSystem Properties for some interesting locations");
		System.out.println();
		System.out.println("\t\tuser.dir: \t\t" + System.getProperty("user.dir"));
		System.out.println("\t\tuser.home: \t\t" + System.getProperty("user.home"));
		System.out.println("\t\tjava.io.tmpdir: \t" + System.getProperty("java.io.tmpdir"));
		System.out.println();
		System.out.println();

		try {

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

			if (args.length == 0) {
				propertyFileName = new String("updateDirs.properties");
				Properties updateDirectories = new Properties();

				String userDirectory = System.getProperty("user.dir");
				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;
				}

				System.out.println("\tUsing properties from " + EOL + "\t\t" + propertiesSource);
				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")) {
				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 = "_";

	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);
		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);
			}
			else {
				if (!mainDirectory.isDirectory()) {
					System.err.println("We expect to get directory names as the input.");
				}
				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");
					createTagFileALL(newFileName + "-All");

				}

			}
		}

	}

	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");
			System.out.println("featureName: " + wholeName);
			System.out.println("projectId: " + projectId);
			System.out.println("versionString: " + versionString);
			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);
			System.out.println("\t\t\t" + "number of features: " + nFeatures);
			System.out.println("\t\t\t" + " number of plugins: " + nPlugins);
		}
	}

	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");
		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());
			}
		}
		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("-")) {
			name = name.substring(1);
		}
		if (!name.endsWith("-")) {
			name = name + "-";
		}
		name = name + "Tags" + "." + "xmlinc";
		// 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);
						System.out.println("\t\t" + version + " greater then " + currentVersion);
					}
				}
			}
		}

	}

	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")) {
				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;

		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");
		}

		writer.write(EOL);
		writer.write("\t" + tagStart + EOL);
		writer.write("\t\t" + urlAttrib + EOL);
		writer.write(EOL);
		writer.flush();

		totalTags++;

	}
}
