package com.seleniumtests.reporter;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.log4j.Logger;

import com.seleniumtests.controller.AbstractPageListener;
import com.seleniumtests.driver.web.element.IPage;
import com.seleniumtests.reporter.pluginmodel.Mauiplugins;
import com.seleniumtests.reporter.pluginmodel.Method;
import com.seleniumtests.reporter.pluginmodel.Page;
import com.seleniumtests.reporter.pluginmodel.Plugin;
import com.seleniumtests.reporter.pluginmodel.Test;

public class PluginsUtil {
	private static final Logger logger = Logger.getLogger(PluginsUtil.class);
	private static Map<String, AbstractPageListener> pageListenerMap = Collections
			.synchronizedMap(new HashMap<String, AbstractPageListener>());

	private static final PluginsUtil _instance = new PluginsUtil();

	public static synchronized PluginsUtil getInstance() {
		return _instance;
	}

	private Mauiplugins _mauiPlugins = null;

	public Mauiplugins getMauiplugins() {
		return _mauiPlugins;
	}

	public List<AbstractPageListener> getPageListeners() {
		List<AbstractPageListener> tempPageListenerList = Collections
				.synchronizedList(new ArrayList<AbstractPageListener>());
		tempPageListenerList.addAll(pageListenerMap.values());

		return tempPageListenerList;
	}

	public void invokePageListeners(String testMethodSignature, IPage page,
			boolean isPageLoad) {

		if (_mauiPlugins == null)
			return;

		List<AbstractPageListener> pageListenerList = new ArrayList<AbstractPageListener>();

		for (Plugin plugin : _mauiPlugins.getPlugin()) {
			if (isPageListenerApplicable(plugin, testMethodSignature, page
					.getClass().getCanonicalName()))
				pageListenerList.add(pageListenerMap.get(plugin.getClassName()
						.trim()));
		}

		for (AbstractPageListener listener : pageListenerList) {
			try {
				if (isPageLoad)
					listener.onPageLoad(page);
				else
					listener.onPageUnload(page);
			} catch (Throwable e) {
				logger.error(e);
			}
		}
	}

	public boolean isPageListenerApplicable(Plugin plugin,
			String testMethodSignature, String pageClassName) {
		if (testMethodSignature == null)
			return true;// for null context sinario
		boolean testFound = false;
		for (Test test : plugin.getTest()) {
			if (testMethodSignature.matches(test.getClassName() + "\\.\\w.*")) {
				// Take care of test class level pages
				for (Page page : test.getPage()) {
					if (pageClassName.matches(page.getClassName())) {
						// return true;
						testFound = true;
						break;
					}
				}

				if (testFound) {
					// Now let's look at the method level pages
					for (Method method : test.getMethod()) {
						if (testMethodSignature.matches(test.getClassName()
								+ "\\." + method.getName() + ".*")) {
							for (Page page : method.getPage()) {
								if (pageClassName.matches(page.getClassName()))
									return true;
							}
							return false;
						}
					}
					return true;
				}
			}
		}

		return false;
	}

	public boolean isTestResultEffected(String pageListenerClassName) {
		AbstractPageListener listener = pageListenerMap
				.get(pageListenerClassName);
		if (listener != null)
			return listener.isTestResultEffected();
		return false;
	}

	public void loadPlugins(File path) {
		logger.info("Loading MAUI Plugins from " + path + " ...");

		InputStream is = null;
		try {
			is = new FileInputStream(path);
			JAXBContext jc = JAXBContext
					.newInstance("com.ebay.maui.reporter.pluginmodel");
			Unmarshaller u = jc.createUnmarshaller();
			_mauiPlugins = (Mauiplugins) u.unmarshal(is);

			for (Plugin plugin : _mauiPlugins.getPlugin()) {
				try {
					pageListenerMap
							.put(plugin.getClassName().trim(),
									(AbstractPageListener) Class.forName(
											plugin.getClassName().trim())
											.newInstance());
				} catch (Exception e) {
					logger.error("Unable to load MAUI Plugins.", e);
				}
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
		}
	}
}

@@ -337,24 +337,73 @@
 arshaller;%0A%0A
+import com.seleniumtests.reporter.pluginmodel.*;%0A
 import org.a
@@ -582,231 +582,28 @@
 del.
-Mauiplugins;%0Aimport com.seleniumtests.reporter.pluginmodel.Method;%0Aimport com.s
+S
 elenium
-t
+T
 ests
-.reporter.pluginmodel.Page;%0Aimport com.seleniumtests.reporter.pluginmodel.Plugin;%0Aimport com.seleniumtests.reporter.pluginmodel.Test
+Plugins
 ;%0A%0Ap
@@ -1009,70 +1009,106 @@
 ate 
-Mauiplugins _mauiPlugins = null;%0A%0A%09public Mauiplugins getMauip
+SeleniumTestsPlugins _seleniumTestsPlugins = null;%0A%0A%09public SeleniumTestsPlugins getSeleniumTestsP
 lugi
@@ -1124,20 +1124,29 @@
 return _
-maui
+seleniumTests
 Plugins;
@@ -1531,20 +1531,29 @@
 %0A%09%09if (_
-maui
+seleniumTests
 Plugins 
@@ -1677,36 +1677,45 @@
 lugin plugin : _
-maui
+seleniumTests
 Plugins.getPlugi
@@ -3418,20 +3418,30 @@
 Loading 
-MAUI
+Selenium Tests
  Plugins
@@ -3594,17 +3594,21 @@
 com.
-ebay.maui
+seleniumtests
 .rep
@@ -3681,28 +3681,46 @@
 %09%09%09_
-mauiPlugins = (Mauip
+seleniumTestsPlugins = (SeleniumTestsP
 lugi
@@ -3770,12 +3770,21 @@
  : _
-maui
+seleniumTests
 Plug
@@ -4057,13 +4057,8 @@
 oad 
-MAUI 
 Plug

refactor class