/*******************************************************************************
 * Copyright (c) 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
 *******************************************************************************/
package org.eclipse.wst.sse.core.tests.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import junit.framework.TestCase;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.sse.core.internal.util.JarUtilities;
import org.eclipse.wst.sse.core.tests.SSEModelTestsPlugin;


/**
 * Tests for org.eclipse.wst.sse.core.internal.util.JarUtilities
 */
public class TestJarUtilities extends TestCase {

	private static final String[] fExpectedNames = new String[]{".project", "about.html", "build.properties", "plugin.properties", "test.xml"};
	private static final String TEST_JAR_UTILITIES_PROJECT = "TestJarUtilities";
	private static final String TEST_JAR_UTILITIES_TESTFILE_JAR = "TestJarUtilities/testfile.jar";
	private static final String TESTFILE_BUNDLE_ENTRY = "resources/testfile.jar";

	static IFile _copyBundleEntryIntoWorkspace(String entryname, String fullPath) throws Exception {
		IFile file = null;
		URL entry = SSEModelTestsPlugin.getDefault().getBundle().getEntry(entryname);
		if (entry != null) {
			IPath path = new Path(fullPath);
			byte[] b = new byte[2048];
			InputStream input = entry.openStream();
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			int i = -1;
			while ((i = input.read(b)) > -1) {
				output.write(b, 0, i);
			}
			file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			if (file != null) {
				if (!file.exists()) {
					file.create(new ByteArrayInputStream(output.toByteArray()), true, new NullProgressMonitor());
				}
				else {
					file.setContents(new ByteArrayInputStream(output.toByteArray()), true, false, new NullProgressMonitor());
				}
			}
		}
		else {
			System.err.println("can't find " + entryname);
		}
		return file;
	}

	static IFile copyBundleEntryIntoWorkspace(final String entryname, final String fullPath) throws Exception {
		final IFile file[] = new IFile[1];
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				try {
					file[0] = _copyBundleEntryIntoWorkspace(entryname, fullPath);
				}
				catch (Exception e) {
					throw new CoreException(new Status(IStatus.ERROR, SSEModelTestsPlugin.getDefault().getBundle().getSymbolicName(), 0, null, e));
				}
				ResourcesPlugin.getWorkspace().checkpoint(true);
			}
		};
		ResourcesPlugin.getWorkspace().run(runnable, new NullProgressMonitor());
		return file[0];
	}

	/**
	 * Creates a simple project.
	 * 
	 * @param name
	 *            - the name of the project
	 * @return
	 */
	static IProject createSimpleProject(String name) {
		IProjectDescription description = ResourcesPlugin.getWorkspace().newProjectDescription(name);
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
		try {
			project.create(description, new NullProgressMonitor());
			project.open(new NullProgressMonitor());
		}
		catch (CoreException e) {
			e.printStackTrace();
		}
		return project;
	}

	private int running = 0;

	public TestJarUtilities() {
		super("JarUtilities Tests");
	}

	private String readContents(InputStream is) {
		String charset = "utf8";

		StringBuffer s = new StringBuffer();
		Reader reader = null;
		try {
			reader = new InputStreamReader(is, charset);
			char[] readBuffer = new char[2048];
			int n = reader.read(readBuffer);
			while (n > 0) {
				s.append(readBuffer, 0, n);
				n = reader.read(readBuffer);
			}

		}
		catch (Exception e) {
		}
		finally {
			try {
				if (is != null) {
					is.close();
				}
				if (reader != null)
					reader.close();
			}
			catch (Exception e) {
				// nothing to do
			}
		}
		return s.toString();
	}

	protected void setUp() throws Exception {
		super.setUp();
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TEST_JAR_UTILITIES_PROJECT);
		synchronized (TEST_JAR_UTILITIES_PROJECT) {
			if (!project.isAccessible()) {
				project = createSimpleProject(TEST_JAR_UTILITIES_PROJECT);
				copyBundleEntryIntoWorkspace(TESTFILE_BUNDLE_ENTRY, TEST_JAR_UTILITIES_TESTFILE_JAR);
			}
		}
		running++;
	}

	protected void tearDown() throws Exception {
		super.tearDown();
		running--;
		if (running == 0) {
			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TEST_JAR_UTILITIES_PROJECT);
			synchronized (TEST_JAR_UTILITIES_PROJECT) {
				project.delete(true, true, null);
			}
		}
	}

	public void testEntryCountFromFilesystem() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString());
		assertEquals("incorrect number of entries", 5, entryNames.length);
	}

	public void testEntryCountFromMissingFile() {
		String[] names = JarUtilities.getEntryNames(TEST_JAR_UTILITIES_PROJECT + "/nonexistent.jar");
		assertNotNull("null names", names);
		assertEquals("entries returned for missing file", 0, names.length);
	}


	public void testEntryCountFromWorkspace() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)));
		assertEquals("incorrect number of entries", 5, entryNames.length);
	}

	public void testEntryCountWithDirectoriesFromFilesystem() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString(), false);
		assertEquals("incorrect number of entries", 6, entryNames.length);
	}

	public void testEntryNamesFromFilesystem() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString());
		Collection names = new ArrayList(Arrays.asList(entryNames));

		String[] expectedNames = new String[]{".project", "about.html", "build.properties", "plugin.properties", "test.xml"};
		for (int i = 0; i < expectedNames.length; i++) {
			assertTrue("missing name of entry: " + entryNames[i], names.contains(entryNames[i]));
		}
	}

	public void testEntryNamesFromWorkspace() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)));
		Collection names = new ArrayList(Arrays.asList(entryNames));

		for (int i = 0; i < fExpectedNames.length; i++) {
			assertTrue("missing name of entry: " + entryNames[i], names.contains(entryNames[i]));
		}
	}

	public void testEntryNamesWithDirectoriesFromFilesystem() {
		String[] entryNames = JarUtilities.getEntryNames(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString(), false);
		Collection names = new ArrayList(Arrays.asList(entryNames));

		String[] expectedNames = new String[]{".project", "about.html", "build.properties", "plugin.properties", "test.xml"};
		for (int i = 0; i < expectedNames.length; i++) {
			assertTrue("missing name of entry: " + entryNames[i], names.contains(entryNames[i]));
		}
		assertTrue("missing name of folder entry: empty/", names.contains("empty/"));
	}

	public void testReadFromFilesystem() {
		String location = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString();
		String contents = readContents(JarUtilities.getInputStream(location, "plugin.properties"));
		assertNotNull("no contents loaded", contents);
		assertTrue("not enough contents read", contents.length() > 40);
		assertTrue("contents not as expected" + contents.substring(0, 40), contents.startsWith("##########################################################"));
	}



	public void testReadFromMissingFile() {
		InputStream contents = JarUtilities.getInputStream(TEST_JAR_UTILITIES_PROJECT + "/nonexistent.jar", "plugin.properties");
		assertNull("contents loaded", contents);
	}

	public void testReadFromSupportedURL() throws MalformedURLException {
		String location = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR)).getLocation().toString();
		String contents = readContents(JarUtilities.getInputStream(new URL("jar:file:" + location + "!/plugin.properties")));
		assertNotNull("no contents loaded", contents);
		assertTrue("not enough contents read", contents.length() > 0);
		assertTrue("contents not as expected", contents.startsWith("##########################################################"));
	}

	public void testReadFromUnsupportedURL() {
		URL entry = SSEModelTestsPlugin.getDefault().getBundle().getEntry("about.html");
		String contents = readContents(JarUtilities.getInputStream(entry));
		assertNotNull("no contents loaded", contents);
		assertTrue("not enough contents read", contents.length() > 750);
		assertTrue("contents not as expected" + contents.substring(0, 75), contents.indexOf("DOCTYPE") > 0);
	}

	public void testReadFromWorkspace() {
		IResource jar = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(TEST_JAR_UTILITIES_TESTFILE_JAR));
		String contents = readContents(JarUtilities.getInputStream(jar, "plugin.properties"));
		assertNotNull("no contents loaded", contents);
		assertTrue("not enough contents read", contents.length() > 40);
		assertTrue("contents not as expected" + contents.substring(0, 40), contents.startsWith("##########################################################"));
	}

}
