/*
 * Created on 2004-7-23
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package org.huihoo.willow.tomcat;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.StringTokenizer;

import org.huihoo.willow.Globals;
import org.huihoo.willow.bootstrap.WebServerFactory;

/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class TomcatServer implements WebServerFactory
{
	// -------------------------------------------------------------- MatrixClient

	protected static final String CATALINA_HOME_TOKEN = "${catalina.home}";
	protected static final String CATALINA_BASE_TOKEN = "${catalina.base}";

	static {
		initDirs();
	}

	public String findProviderClass() throws Exception
	{
		return "org.huihoo.willow.tomcat.TomcatProvider";
	}

	public ArrayList createRepository(String name) throws Exception
	{
		String value = CatalinaProperties.getProperty(name + ".loader");
		if ((value == null) || (value.equals("")))
		{
			return new ArrayList(0);
		}

		ArrayList unpackedList = new ArrayList();
		ArrayList packedList = new ArrayList();
		ArrayList urlList = new ArrayList();

		StringTokenizer tokenizer = new StringTokenizer(value, ",");
		while (tokenizer.hasMoreElements())
		{
			String repository = tokenizer.nextToken();
			// Check for a JAR URL repository
			try
			{
				urlList.add(new URL(repository));
				continue;
			}
			catch (MalformedURLException e)
			{
				// Ignore
			}
			// Local repository
			boolean packed = false;
			if (repository.startsWith(CATALINA_HOME_TOKEN))
			{
				repository = getCatalinaHome() + repository.substring(CATALINA_HOME_TOKEN.length());
			}
			else if (repository.startsWith(CATALINA_BASE_TOKEN))
			{
				repository = getCatalinaBase() + repository.substring(CATALINA_BASE_TOKEN.length());
			}

			if (repository.endsWith("*.jar"))
			{
				packed = true;
				repository = repository.substring(0, repository.length() - "*.jar".length());
			}
			if (packed)
			{
				packedList.add(new File(repository));
			}
			else
			{
				unpackedList.add(new File(repository));
			}
		}
		
		if("common".equals(name))
		{
			packedList.add(new File(getCatalinaBase(),"bin/bootstrap.jar"));
		}
		
		File[] unpacked = (File[]) unpackedList.toArray(new File[0]);
		File[] packed = (File[]) packedList.toArray(new File[0]);
		URL[] urls = (URL[]) urlList.toArray(new URL[0]);

		return createRepository(unpacked, packed, urls);
	}
	private static ArrayList createRepository(File unpacked[], File packed[], URL urls[])
		throws Exception
	{
		// Construct the "class path" for this class loader
		ArrayList list = new ArrayList();

		// Add unpacked directories
		if (unpacked != null)
		{
			for (int i = 0; i < unpacked.length; i++)
			{
				File file = unpacked[i];
				if (!file.exists() || !file.canRead())
				{
					continue;
				}
				URL url = new URL("file", null, file.getCanonicalPath() + File.separator);
				list.add(url);
			}
		}

		// Add packed directory JAR files
		if (packed != null)
		{
			for (int i = 0; i < packed.length; i++)
			{
				File directory = packed[i];
				if (!directory.isDirectory() || !directory.exists() || !directory.canRead())
					continue;
				String filenames[] = directory.list();
				for (int j = 0; j < filenames.length; j++)
				{
					String filename = filenames[j].toLowerCase();
					if (!filename.endsWith(".jar"))
					{
						continue;
					}
					File file = new File(directory, filenames[j]);
					URL url = new URL("file", null, file.getCanonicalPath());
					list.add(url);
				}
			}
		}

		// Add URLs
		if (urls != null)
		{
			for (int i = 0; i < urls.length; i++)
			{
				list.add(urls[i]);
			}
		}
		return (list);
	}

	/**
	* Get the value of the catalina.home environment variable.
	*/
	private static String getCatalinaHome()
	{
		return System.getProperty("catalina.home");
	}

	/**
	 * Get the value of the catalina.base environment variable.
	 */
	private static String getCatalinaBase()
	{
		return System.getProperty("catalina.base");
	}

	private static void initDirs()
	{

		String catalinaHome = System.getProperty("catalina.home");
		if (catalinaHome == null)
		{
			if (System.getProperty("catalina.base") != null)
			{
				catalinaHome = System.getProperty("catalina.base");
			}
			else
			{
				File tomcatHome = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), "catalina");
				try
				{
					catalinaHome = tomcatHome.getCanonicalPath();
				}
				catch (IOException e)
				{
					catalinaHome = tomcatHome.getAbsolutePath();
				}
			}
		}

		if (catalinaHome != null)
		{
			File home = new File(catalinaHome);
			if (!home.isAbsolute())
			{
				try
				{
					catalinaHome = home.getCanonicalPath();
				}
				catch (IOException e)
				{
					catalinaHome = home.getAbsolutePath();
				}
			}
			System.setProperty("catalina.home", catalinaHome);
		}

		if (System.getProperty("catalina.base") == null)
		{
			System.setProperty("catalina.base", System.getProperty("catalina.home"));
		}
		else
		{
			String catalinaBase = System.getProperty("catalina.base");
			File base = new File(catalinaBase);
			if (!base.isAbsolute())
			{
				try
				{
					catalinaBase = base.getCanonicalPath();
				}
				catch (IOException e)
				{
					catalinaBase = base.getAbsolutePath();
				}
			}
			System.setProperty("catalina.base", catalinaBase);
		}
	}
}