/*******************************************************************************
 * Copyright (c) 2006 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.jst.server.core.tests.j2ee;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jst.server.core.IEnterpriseApplication;
import org.eclipse.jst.server.core.IJ2EEModule;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.jst.server.core.tests.AllTests;
import org.eclipse.wst.server.core.*;

import junit.framework.TestCase;
/**
 * TODO Tests left to do:
 *    migrated modules
 *    flat project structure
 *    complex .component structures
 *    external jar references for EAR or WEB
 */
public class ModuleTestCase extends TestCase {
	private static final String RUNTIME_TYPE_ID = "org.eclipse.jst.server.core.runtimeType";

	private static final String[] PROJECT_NAMES = new String[] {
		"PublishTestEAR", "PublishTestEJB", "PublishTestUtil", "PublishTestUtil2",
		"PublishTestWeb", "PublishTestWeb2", "PublishTestConnector", "PublishTestClient"
	};

	protected static IRuntime runtime;
	protected static IModule module;
	protected static IEnterpriseApplication ent;
	protected static IWebModule webModule;
	protected static IJ2EEModule j2eeModule;

	public void test000CreateRuntime() throws Exception {
		IRuntimeType rt = ServerCore.findRuntimeType(RUNTIME_TYPE_ID);
		IRuntimeWorkingCopy wc = rt.createRuntime("RuntimeLibraries", null);
		wc.setLocation(AllTests.runtimeLocation);
		wc.setName("RuntimeLibraries");
		runtime = wc.save(false, null);
		
		assertTrue(!runtime.isWorkingCopy());
	}

	public void test001ImportModules() throws Exception {
		ModuleHelper.importProject("PublishEAR.zip", PROJECT_NAMES);
	}

	public void test002IncrementalBuild() throws Exception {
		ModuleHelper.buildIncremental();
	}

	public void test003NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.ear").length, 1);
	}

	public void test004NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.web").length, 2);
	}

	public void test005NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.ejb").length, 1);
	}

	public void test006NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.utility").length, 2);
	}

	public void test007NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.appclient").length, 1);
	}
	
	public void test008NumModules() throws Exception {
		assertEquals(ServerUtil.getModules("jst.connector").length, 1);
	}


	// ---------- EAR tests ----------

	public void test020EAR() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestEAR");
		assertNotNull(module);
	}

	public void test021EAR() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/application.xml"))
			fail();
	}

	public void test022EAR() throws Exception {
		if (!ModuleHelper.fileExists(module, "test.jar"))
			fail();
	}

	public void test023EAR() throws Exception {
		if (!ModuleHelper.fileExists(module, "jarfolder/test3.jar"))
			fail();
	}

	public void test024EAR() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 3);
	}

	public void test025EAR() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 2);
	}

	public void test026EAR() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.ear");
	}

	public void test027EAR() throws Exception {
		ent = (IEnterpriseApplication) module.loadAdapter(IEnterpriseApplication.class, null);
		assertNotNull(ent);
	}

	public void test028EAR() throws Exception {
		assertEquals(ent.getResourceFolders().length, 1);
	}

	public void test029EAR() throws Exception {
		assertEquals(ent.getModules().length, 6);
	}

	public void _test030EAR() throws Exception {
		IModule[] modules = ent.getModules();
		int size = modules.length;
		List<String> list = new ArrayList<String>(size);
		for (int i = 0; i < size; i++) {
			System.out.println(modules[i].getName());
			list.add(modules[i].getName());
		}
		
		String[] s = new String[] {
			"PublishTestEJB", "PublishTestUtil2", "PublishTestWeb",
			"PublishTestWeb2", "PublishTestConnector", "PublishTestClient"
		};
		
		size = s.length;
		for (int i = 0; i < size; i++) {
			if (!list.contains(s[i]))
				fail("EAR does not contain " + s[i]);
		}
	}


	// ---------- Utility 1 tests ----------

	public void test040Util() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestUtil");
		assertNotNull(module);
	}

	public void test041Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test042Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "test.properties"))
			fail();
	}

	public void test043Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "publish/TestUtil.class"))
			fail();
	}

	public void test044Util() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 3);
	}

	public void test045Util() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 2);
	}

	public void test046Util() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.utility");
	}

	public void test047Util() throws Exception {
		j2eeModule = (IJ2EEModule) module.loadAdapter(IJ2EEModule.class, null);
		assertNotNull(j2eeModule);
	}

	public void test048Util() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test049Util() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test050Util() throws Exception {
		assertFalse(j2eeModule.isBinary());
	}


	// ---------- Utility 2 tests ----------

	public void test060Util() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestUtil2");
		assertNotNull(module);
	}

	public void test061Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test062Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "temp/test.properties"))
			fail();
	}

	public void test063Util() throws Exception {
		if (!ModuleHelper.fileExists(module, "publish/TestUtil2.class"))
			fail();
	}

	public void test064Util() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 3);
	}

	public void test065Util() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 3);
	}

	public void test066Util() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.utility");
	}

	public void test067Util() throws Exception {
		j2eeModule = (IJ2EEModule) module.loadAdapter(IJ2EEModule.class, null);
		assertNotNull(j2eeModule);
	}

	public void test068Util() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test069Util() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test070Util() throws Exception {
		assertFalse(j2eeModule.isBinary());
	}


	// ---------- EJB tests ----------

	public void test080EJB() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestEJB");
		assertNotNull(module);
	}

	public void test081EJB() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test082EJB() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/ejb-jar.xml"))
			fail();
	}

	public void test083EJB() throws Exception {
		if (!ModuleHelper.fileExists(module, "ejbs/MyBeanLocalHome.class"))
			fail();
	}

	public void test084EJB() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 7);
	}

	public void test085EJB() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 2);
	}

	public void test086EJB() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.ejb");
	}

	public void test087EJB() throws Exception {
		j2eeModule = (IJ2EEModule) module.loadAdapter(IJ2EEModule.class, null);
		assertNotNull(j2eeModule);
	}

	public void test088EJB() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test089EJB() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test090EJB() throws Exception {
		assertFalse(j2eeModule.isBinary());
	}


	// ---------- Connector tests ----------

	public void test100Connector() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestConnector");
		assertNotNull(module);
	}

	public void test101Connector() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test102Connector() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/ra.xml"))
			fail();
	}

	public void test103Connector() throws Exception {
		if (!ModuleHelper.fileExists(module, "test/MyOtherConnectorClass.class"))
			fail();
	}

	public void test104Connector() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 5);
	}

	public void test105Connector() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 3);
	}

	public void test106Connector() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.connector");
	}

	public void test107Connector() throws Exception {
		j2eeModule = (IJ2EEModule) module.loadAdapter(IJ2EEModule.class, null);
		assertNotNull(j2eeModule);
	}

	public void test108Connector() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test109Connector() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test110Connector() throws Exception {
		assertFalse(j2eeModule.isBinary());
	}


	// ---------- Client tests ----------

	public void test120Client() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestClient");
		assertNotNull(module);
	}

	public void test121Client() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test122Client() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/application-client.xml"))
			fail();
	}

	public void test123Client() throws Exception {
		if (!ModuleHelper.fileExists(module, "Main.class"))
			fail();
	}

	public void test124Client() throws Exception {
		if (!ModuleHelper.fileExists(module, "Main2.class"))
			fail();
	}

	public void test125Client() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 4);
	}

	public void test126Client() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 1);
	}

	public void test127Client() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.appclient");
	}

	public void test128Client() throws Exception {
		j2eeModule = (IJ2EEModule) module.loadAdapter(IJ2EEModule.class, null);
		assertNotNull(j2eeModule);
	}

	public void test129Client() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test130Client() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test131Client() throws Exception {
		assertFalse(j2eeModule.isBinary());
	}


	// ---------- Web 1 tests ----------

	public void test140Web() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestWeb");
		assertNotNull(module);
	}

	public void test141Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test142Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/web.xml"))
			fail();
	}

	public void test143Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "test.jsp"))
			fail();
	}

	public void test144Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/classes/servtest/TestServlet2.class"))
			fail();
	}

	public void test145Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/classes/servtest/TestServlet.class"))
			fail();
	}

	public void test146Web() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 5);
	}

	public void test147Web() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 5);
	}

	public void test148Web() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.web");
	}

	public void test149Web() throws Exception {
		webModule = (IWebModule) module.loadAdapter(IWebModule.class, null);
		j2eeModule = webModule;
		assertNotNull(j2eeModule);
	}

	public void test150Web() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test151Web() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test152Web() throws Exception {
		assertEquals(webModule.getModules().length, 1);
	}

	public void test153Web() throws Exception {
		assertEquals(webModule.getModules()[0].getName(), "PublishTestUtil");
	}

	public void test154Web() throws Exception {
		assertEquals(webModule.getContextRoot(), "PublishTestWeb");
	}

	public void test155Web() throws Exception {
		assertFalse(webModule.isBinary());
	}

	// ---------- Web 2 tests ----------

	public void test160Web() throws Exception {
		module = ModuleHelper.getModuleFromProject("PublishTestWeb2");
		assertNotNull(module);
	}

	public void test161Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "META-INF/MANIFEST.MF"))
			fail();
	}

	public void test162Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/web.xml"))
			fail();
	}

	public void test163Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/lib/test.jar"))
			fail();
	}

	public void test164Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/classes/serv/AServlet.class"))
			fail();
	}

	public void test165Web() throws Exception {
		if (!ModuleHelper.fileExists(module, "WEB-INF/classes/serv/BServlet.class"))
			fail();
	}

	public void test166Web() throws Exception {
		assertEquals(ModuleHelper.countFiles(module), 5);
	}

	public void test167Web() throws Exception {
		assertEquals(ModuleHelper.countFolders(module), 5);
	}

	public void test168Web() throws Exception {
		assertEquals(module.getModuleType().getId(), "jst.web");
	}

	public void test169Web() throws Exception {
		webModule = (IWebModule) module.loadAdapter(IWebModule.class, null);
		j2eeModule = webModule;
		assertNotNull(j2eeModule);
	}

	public void test170Web() throws Exception {
		assertEquals(j2eeModule.getResourceFolders().length, 1);
	}

	public void test171Web() throws Exception {
		assertEquals(j2eeModule.getJavaOutputFolders().length, 1);
	}

	public void test172Web() throws Exception {
		assertEquals(webModule.getModules().length, 0);
	}

	public void test173Web() throws Exception {
		assertEquals(webModule.getContextRoot(), "PublishTestWeb2");
	}

	public void test174Web() throws Exception {
		assertFalse(webModule.isBinary());
	}


	public void test199Cleanup() throws Exception {
		int size = PROJECT_NAMES.length;
		for (int i = 0; i < size; i++) {
			ModuleHelper.deleteProject(PROJECT_NAMES[i]);
		}
	}
}