/*******************************************************************************
 * Copyright (c) 2007, 2009 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
 * This file originally came from 'Eclipse Orbit' project then adapted to use 
 * in WTP and improved to use 'Manifest' to read manifest.mf, instead of reading 
 * it as a properties file.
 ******************************************************************************/
package org.eclipse.galileo.tests;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.apache.tools.ant.BuildException;
import org.eclipse.internal.provisional.equinox.p2.jarprocessor.JarProcessor;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @since 3.3
 */
public class BREETest extends TestCase {

	private static final String EXTENSION_JAR = ".jar";
	private static final String EXTENSION_PACEKD_JAR = ".jar.pack.gz";
	private static final String EXTENSION_ZIP = ".zip";
	private static final Object PROPERTY_BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
	private static final FullJarNameParser nameParser = new FullJarNameParser();
	private static final String BACKSLASH = "\\";
	private static final String LITERAL_PERIOD = BACKSLASH + ".";
	private static final String ANY = ".*";

	public static void main(String[] args) {
		System.out.println("start BREE Checks main");
		BREETest testlayout = new BREETest();
		testlayout.setDirectoryToCheck("D:\\temptest");
		testlayout.testBREESettingRule();

	}

	public static Test suite() {
		return new TestSuite(BREETest.class);
	}

	private String directoryToCheck;
	private String tempWorkingDir;


	public String getDirectoryToCheck() {
		return directoryToCheck;
	}

	public void setDirectoryToCheck(String bundleDirToCheck) {
		this.directoryToCheck = bundleDirToCheck;
	}

	public boolean testBREESettingRule() {

		String property = getDirectoryToCheck();
		assertNotNull("Need to set input directory to check against.", property);
		String bundleDirectory = null;
		if (property.endsWith("/")) {
			bundleDirectory = property + "plugins";
		}
		else {
			bundleDirectory = property + "/plugins";
		}
		File inputdir = new File(bundleDirectory);
		assertTrue("bundle direcotry (" + bundleDirectory + ") must be an existing directory.", inputdir.exists() && inputdir.isDirectory());

		boolean failuresOccured = checkBundleBREE(inputdir);
		return failuresOccured;
	}

	private boolean checkBundleBREE(File inputdir) {
		// reset/initialize errors
		InputStream propertyStream = this.getClass().getResourceAsStream("exceptions.properties");
		Properties breeExceptionProperties = new Properties();
		String breeExceptions = "";
		try {
			breeExceptionProperties.load(propertyStream);
			breeExceptions = breeExceptionProperties.getProperty("breeExceptions");
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if (propertyStream != null) {
				try {
					propertyStream.close();
				}
				catch (IOException e) {
					// would be unusual to get here?
					e.printStackTrace();
				}
			}
		}
		List errors = new ArrayList();
		Map javaWithBree = new HashMap();
		List nonjavaWithBree = new ArrayList();
		List javaWithoutBree = new ArrayList();
		int nonJavaNoBREE = 0;
		boolean failuresOccured = false;
		File[] children = inputdir.listFiles();
		int totalsize = children.length;
		int checked = 0;
		for (int i = 0; i < totalsize; i++) {
			File child = children[i];
			String name = child.getName();
			if (child.getName().toLowerCase().endsWith(EXTENSION_PACEKD_JAR)) {
				child = getFileFromPACKEDJAR(child);
			}
			if (child != null) {
				String bundleName = getBundleName(child.getName());
				if (bundleName != null && !breeExceptions.contains(bundleName)) {
					checked++;
					String bree = getBREEFromJAR(child);
					if (bree != null && bree.length() > 0) {
						// has BREE, confirm is java file
						if (containsJava(child)) {
							incrementCounts(javaWithBree, bree);
						}
						else {
							trackFalseInclusions(nonjavaWithBree, child);
							failuresOccured = true;
						}
					}
					else {
						// no BREE, confirm is non-java
						if (containsJava(child)) {
							trackOmissions(javaWithoutBree, child);
							failuresOccured = true;
						}
						else {
							nonJavaNoBREE++;
						}
					}
				}
			}
		}
		System.out.println("   Checked " + checked + " of " + totalsize + ".");

		System.out.println("  Bundles with correct BREE:");
		System.out.println("   Java with BREE: " + totalCount(javaWithBree));
		System.out.println("   Non Java without BREE:" + nonJavaNoBREE);
		System.out.println("    Distribution of BREEs: ");
		Set allBREEs = javaWithBree.keySet();
		for (Object object : allBREEs) {
			Integer count = (Integer) javaWithBree.get(object);
			System.out.println("   " + count.intValue() + "  " + object);
		}

		System.out.println("  Bundles with incorrect BREE:");
		System.out.println("    Java Bundles without BREE: " + javaWithoutBree.size());
		Collections.sort(javaWithoutBree);
		for (Iterator iterator = javaWithoutBree.iterator(); iterator.hasNext();) {
			Object object = (Object) iterator.next();
			System.out.println("       " + object);
		}
		System.out.println("    Non Java Bundles with BREE: " + nonjavaWithBree.size());
		Collections.sort(nonjavaWithBree);
		for (Iterator iterator = nonjavaWithBree.iterator(); iterator.hasNext();) {
			Object object = (Object) iterator.next();
			System.out.println("       " + object);
		}

		return failuresOccured;
	}

	private int totalCount(Map javaWithBree) {

		Collection allCounts = javaWithBree.values();
		int total = 0;
		for (Iterator iterator = allCounts.iterator(); iterator.hasNext();) {
			Integer count = (Integer) iterator.next();
			total = total + count.intValue();
		}
		return total;
	}

	private void trackOmissions(List javaWithoutBree, File child) {
		javaWithoutBree.add(child.getName());

	}

	private void trackFalseInclusions(List list, File child) {
		list.add(child.getName());

	}

	private void incrementCounts(Map breeMap, String bree) {
		Integer count = (Integer) breeMap.get(bree);
		if (count == null) {
			breeMap.put(bree, new Integer(1));
		}
		else {
			breeMap.put(bree, increment(count));
		}

	}

	private Integer increment(Integer count) {
		return new Integer(count.intValue() + 1);
	}

	private boolean containsJava(File jarfile) {
		// We assume the file is a 'jar' file.
		boolean containsJava = false;
		JarFile jar = null;
		try {
			jar = new JarFile(jarfile, false, ZipFile.OPEN_READ);
			Enumeration<JarEntry> entries = jar.entries();
			while (entries.hasMoreElements()) {
				JarEntry entry = entries.nextElement();
				if (entry.getName().endsWith(".class")) {
					containsJava = true;
					break;
				}
				else if (entry.getName().endsWith(".jar")) {
					InputStream input = jar.getInputStream(entry);
					if (containsJava(input)) {
						containsJava = true;
						break;
					}
				}
			}

		}
		catch (IOException e) {
			System.out.println(e.getMessage());
		}
		finally {
			if (jar != null)
				try {
					jar.close();
				}
				catch (IOException e) {
					// ignore
				}
		}
		return containsJava;
	}

	private boolean containsJava(InputStream input) {
		// We assume the file is a 'jar' file.
		boolean containsJava = false;

		try {
			JarInputStream jarInputStream = new JarInputStream(input);
			while (jarInputStream.available() > 0) {
				ZipEntry entry = jarInputStream.getNextEntry();
				if (entry != null) {
					if (entry.getName().endsWith(".class")) {
						containsJava = true;
						break;
					}
				}
			}

		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if (input != null)
				try {
					input.close();
				}
				catch (IOException e) {
					// ignore
				}
		}
		return containsJava;
	}

	private String getBundleName(String fullname) {
		String result = null;
		boolean parsable = nameParser.parse(fullname);
		if (parsable) {
			result = nameParser.getProjectString();
		}
		return result;
	}

	/*
	 * Return the bundle id from the manifest pointed to by the given input
	 * stream.
	 */
	private String getBREEFromManifest(InputStream input, String path) {
		String bree = null;
		try {
			Map attributes = ManifestElement.parseBundleManifest(input, null);
			bree = (String) attributes.get(PROPERTY_BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT);
		}
		catch (BundleException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if (input != null)
				try {
					input.close();
				}
				catch (IOException e) {
					// ignore
				}
		}

		return bree;
	}

	/*
	 * The given file points to a bundle contained in an archive. Look into
	 * the bundle manifest file to find the bundle identifier.
	 */
	private File getFileFromPACKEDJAR(File file) {
		String id = null;
		JarFile jar = null;
		File tmpjar = null;
		try {
			JarProcessor jarprocessor = JarProcessor.getUnpackProcessor(null);
			jarprocessor.setWorkingDirectory(getTempWorkingDir());
			tmpjar = jarprocessor.processJar(file);
		}
		catch (IOException e) {
			e.printStackTrace();
			tmpjar = null;
		}
		return tmpjar;
	}

	public String getTempWorkingDir() {
		return tempWorkingDir;
	}

	public void setTempWorkingDir(String tempWorkingDir) {
		this.tempWorkingDir = tempWorkingDir;
	}

	/*
	 * The given file points to a bundle contained in an archive. Look into
	 * the bundle manifest file to find the bundle identifier.
	 */
	private String getBREEFromJAR(File file) {
		InputStream input = null;
		JarFile jar = null;
		try {
			jar = new JarFile(file, false, ZipFile.OPEN_READ);
			JarEntry entry = jar.getJarEntry(JarFile.MANIFEST_NAME);
			if (entry == null) {
				// addError("Bundle does not contain a MANIFEST.MF file: " +
				// file.getAbsolutePath());
				return null;
			}
			input = jar.getInputStream(entry);
			return getBREEFromManifest(input, file.getAbsolutePath());
		}
		catch (IOException e) {
			System.out.println(e.getMessage());
			// addError(e.getMessage());
			return null;
		}
		finally {
			if (input != null)
				try {
					input.close();
				}
				catch (IOException e) {
					// ignore
				}
			if (jar != null)
				try {
					jar.close();
				}
				catch (IOException e) {
					// ignore
				}
		}
	}
}
