package com.nyl.rnv.rwb.wfc;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.soap.Detail;
import javax.xml.soap.DetailEntry;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.session.Session;
import org.apache.axis.transport.http.AxisHttpSession;
import org.apache.axis.transport.http.HTTPConstants;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.axis.MessageContext;

//import com.nyl.rnv.rwb.admin.TestUser;
import com.nyl.rnv.rwb.admin.Administrator;
import com.nyl.rnv.rwb.admin.AuthenticationManager;
import com.nyl.rnv.rwb.admin.Project;
import com.nyl.rnv.rwb.admin.TestCoordinator;
import com.nyl.rnv.rwb.admin.Tester;
import com.nyl.rnv.rwb.admin.UserManager;
import com.nyl.rnv.rwb.admin.Users;
import com.nyl.rnv.rwb.util.WebServiceUtil;

/**
 * @author t19bgtx
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class WebServiceController {
	String ns;
//	Users tu = new Administrator();
	ServiceLocator sl;
  	Properties prop = new Properties();
  	private static Logger logger = Logger.getLogger("com.nyl.rnv.rwb.wfc.WebServiceController");

	
	public WebServiceController() throws Exception {
		logger.setLevel(Level.INFO);
		logger.info("Initializing the controller.");
	  	try {
	  		logger.info("Loading property file");
			prop.load(new FileInputStream("c:\\webservice.config"));
		  	ns = prop.getProperty("RWB.Service.NAMESPACE");
			sl = new ServiceLocator();
		  	logger.info("Name Space: "+ ns);
		} catch (FileNotFoundException e) {
			String errormsg = "Web service config file does not exit. " + e.getMessage();
			logger.fatal(e.getMessage());
			throw e;
		} catch (IOException e) {
			logger.fatal(e.getMessage());
			throw e;
		}
	  	logger.info("The controller initialization completed.");
	}
	
	public Users LogIn(String loginName, String loginID, String app) throws Exception {
		logger.info("Entering LogIn");
		Users user = null;
		AuthenticationManager mgr = new AuthenticationManager();
		try {
			logger.info("Retrieving current message context");
			MessageContext m = MessageContext.getCurrentContext();
			logger.info("Current message context retreived");
			logger.info("Retrieving HTTP servlet request");
			HttpServletRequest hsr = (HttpServletRequest) m.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
			logger.info("HttpServletRequest: "+hsr);
			logger.info("Retrieving HTTP session");
			HttpSession hs = hsr.getSession();
			logger.info("HttpSession: "+hs);
			logger.info("Creating AXIS session");
			Session s = new AxisHttpSession(hs);
			logger.info("AxisHttpSession: "+s);
			logger.info("Ready to invoke LogIn");
			user = (Users)mgr.Login(loginName, loginID, app);
			logger.info("Invoke completed, Users object returned");
			logger.info("Ready to bind Users object to the AXIS session");
			s.set("user",user);
			logger.info("Users object bound to the AXIS session");
			logger.info("Exiting from LogIn");

			Call call = sl.getCall();
			Object[] params = new Object[3];
			params[0] = loginName;
			params[1] = loginID;
			params[2] = app;
			
			call.setOperationName(new QName(ns, "OpenDB"));
	        call.addParameter(new QName(ns, "UserName"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
	        call.addParameter(new javax.xml.namespace.QName(ns, "PassWord"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
	        call.addParameter(new javax.xml.namespace.QName(ns, "AppName"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
	        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
	        call.setReturnClass(java.lang.String.class);
	        call.setReturnQName(new javax.xml.namespace.QName(ns, "OpenDBResult"));
			call.setProperty(call.SOAPACTION_URI_PROPERTY,ns+"OpenDB");

			logger.info("Ready to invoke OpenDB.");

			try {
				String ret = (String) call.invoke( params );
			} catch (Exception e) {
				logger.fatal(e.getMessage());
				this.LogOut();
				throw e;
			}
			logger.info("Web service call returned.");
		} catch(Exception e) {
			logger.fatal(e.getMessage());
			throw e;
		}
		logger.info("Exiting LogIn");
//		try {
//			sl = new ServiceLocator();
//			Call call = sl.getCall();
//			
//			Object[] params = new Object[3];
//			params[0] = loginName;
//			params[1] = loginID;
//			params[2] = app;
//		  	
//			call.setOperationName(new QName(ns, "OpenDB"));
//	        call.addParameter(new QName(ns, "UserName"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
//	        call.addParameter(new javax.xml.namespace.QName(ns, "PassWord"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
//	        call.addParameter(new javax.xml.namespace.QName(ns, "AppName"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
//	        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
//	        call.setReturnClass(java.lang.String.class);
//	        call.setReturnQName(new javax.xml.namespace.QName(ns, "OpenDBResult"));
//			call.setProperty(call.SOAPACTION_URI_PROPERTY,ns+"OpenDB");
//
//			logger.info("Ready to invoke from LogIn.");
//
//			String ret = (String) call.invoke( params );
//
//			logger.info("Web service call returned without any error.");
//		} catch (Exception e) {
//			logger.fatal(e.getMessage());
//			System.err.println(e.getMessage());
//		}
		return user;
	}
	
	public void LogOut() throws Exception {
		logger.info("Entering LogOut");
		Session session = null;
		try {
			MessageContext m = MessageContext.getCurrentContext();
			HttpServletRequest hsr = (HttpServletRequest) m.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
			HttpSession hs = hsr.getSession();
			session = new AxisHttpSession(hs);
			logger.info("Ready to invalidate the session");
			hs.invalidate();
			logger.info("Session invalidated");
			logger.info("Exiting from LogOut");
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw e;
		}
		logger.info("Exiting LogOut");
//		Users user = null;
//		
//		try {
//			Call call = sl.getCall();
//			call.setOperationName(new QName(ns, "CloseDB"));
//			call.setProperty(call.SOAPACTION_URI_PROPERTY,ns+"CloseDB");
//	        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
//	        call.setReturnClass(java.lang.String.class);
//	        call.setReturnQName(new javax.xml.namespace.QName(ns, "CloseDBResult"));
//			
//			//System.out.println("Session Set");		
//			logger.info("Ready to invoke from LogOut.");
//
//			String ret = (String) call.invoke( new Object[] {} );
//			user = (Users)MessageContext.getCurrentContext().getSession().get("user");
//			//System.out.println(ret);
//			logger.info("Web service call returned without any error.");
//		} catch(Exception e) {
//			System.out.println(e.getMessage());
//		}
//		return user;
	}

	public Users CreateUser(Users newUsr) throws Exception {
		logger.info("Entering CreateUser");
		UserManager mgr = new UserManager();
		Users addedUser = null;
		try {
			logger.info("Retrieving Users object from the session");
			Users user = (Users)MessageContext.getCurrentContext().getSession().get("user");
			logger.info("Users object retrieved");
			logger.info("Ready to invoke CreateUser");
			addedUser = (Users) mgr.CreateUser(user, newUsr);
			logger.info("CreateUser call completed");

			try {
				Call call = sl.getCall();
				
				Object[] params = new Object[3];

				params[0] = addedUser.getLoginName();
				params[1] = addedUser.getPassword();
				params[2] = new Boolean("false");
			  	
				call.setOperationName(new QName(ns, "AddUser"));
		        call.addParameter(new QName(ns, "UserName"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
		        call.addParameter(new javax.xml.namespace.QName(ns, "Password"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
		        call.addParameter(new javax.xml.namespace.QName(ns, "ReadOnly"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
		        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
		        call.setReturnClass(java.lang.String.class);
		        call.setReturnQName(new javax.xml.namespace.QName(ns, "AddUserResult"));
				call.setProperty(call.SOAPACTION_URI_PROPERTY,ns+"AddUser");
	
				logger.info("Ready to invoke AddUser.");
				try {
					String ret = (String) call.invoke( params );
					logger.info("Web service call returned.");
				} catch (Exception e) {
					logger.fatal(e.getMessage());
					throw e;
				}
			} catch (Exception e) {
				logger.fatal(e.getMessage());
				throw e;
			}
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw e;
		}
		logger.info("Exiting from CreateUser");
		return addedUser;
	}

	public CollectionEntryVO[] ListUsers(Users usr, Long projectId) throws Exception {
		logger.info("Entering ListUsers");
		UserManager mgr = new UserManager();
		Collection collection = null;
//		Administrator[] admin = null;
//		Tester[] tester = null;
//		TestCoordinator[] testCoordinator = null;
//		int size1 = 0;
//		int size2 = 0;
//		int size3 = 0;
//		Iterator it = null;
//		UsersVO usersVO = new UsersVO();
		
		try {
			logger.info("Retrieving Users object");
			Users user = (Users)MessageContext.getCurrentContext().getSession().get("user");
			logger.info("Users object retrieved");
			logger.info("Ready to invoke ListUsers");
			collection = mgr.ListUsers(user, projectId);
			
//			it = collection.iterator();
//			Class c = null;
//			while(it.hasNext()) {
//				c = it.next().getClass();
//				if(c == Administrator.class) {
//					size1++;
//				} else if(c == Tester.class) {
//					size2++;
//				} else {
//					size3++;
//				}
//			}
//			admin = new Administrator[size1];
//			tester = new Tester[size2];
//			testCoordinator = new TestCoordinator[size3];
//			it = collection.iterator();
//			c = null;
//			Object obj = null;
//			size1 = 0;
//			size2 = 0;
//			size3 = 0;
//			while(it.hasNext()) {
//				obj = it.next();
//				c = obj.getClass();
//				if(c == Administrator.class) {
//					admin[size1++] = (Administrator) obj;
//				} else if(c == Tester.class) {
//					tester[size2++] = (Tester) obj;
//				} else {
//					testCoordinator[size3++] = (TestCoordinator) obj;
//				}
//			}
//			usersVO.setAdmin(admin);
//			usersVO.setTestCoordinator(testCoordinator);
//			usersVO.setTester(tester);
			logger.info("ListUsers call completed");
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw e;
		}
		logger.info("Exiting ListUsers");
		return WebServiceUtil.convertCollectionToCollectionEntryVO(collection);
	}
	
	public void DeleteUser(Users usr, Users usrToBeDeleted) throws Exception {
		logger.info("Entering DeleteUser");
		UserManager mgr = new UserManager();
		
		try {
			logger.info("Retrieving Users object");
			Users user = (Users)MessageContext.getCurrentContext().getSession().get("user");
			logger.info("Users object retrieved");
			logger.info("Ready to invoke DeleteUser");
			mgr.DeleteUser(user, usrToBeDeleted);
			logger.info("DeleteUser call completed");
			
			try {
				Call call = sl.getCall();
				
				Object[] params = new Object[1];

				params[0] = usrToBeDeleted.getLoginName();
			  	
				call.setOperationName(new QName(ns, "DeleteUser"));
		        call.addParameter(new QName(ns, "UserName"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
		        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
		        call.setReturnClass(java.lang.String.class);
		        call.setReturnQName(new javax.xml.namespace.QName(ns, "DeleteUserResult"));
				call.setProperty(call.SOAPACTION_URI_PROPERTY,ns+"DeleteUser");
	
				logger.info("Ready to invoke DeleteUser.");
				try {
					String ret = (String) call.invoke( params );
					logger.info("Web service call returned.");
				} catch (Exception e) {
					logger.fatal(e.getMessage());
					//Need to rollback Axis call here
					throw e;
				}
			} catch (Exception e) {
				logger.fatal(e.getMessage());
				throw e;
			}		
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw e;
		}
		logger.info("Exiting DeleteUser");
	}
 }
