package com.ferienclub.mb;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.mule.extras.client.MuleClient;
import org.mule.impl.RequestContext;
import org.mule.umo.UMOEventContext;
import org.mule.umo.UMOException;
import org.mule.umo.UMOMessage;

import com.ferienclub.custadmin.beans.HistoryEntry;
import com.ferienclub.custadmin.beans.User;
import com.ferienclub.mb.interfaces.IMakeBookingPM;
import com.ferienclub.vacancymgm.beans.Booking;

public class MakeBookingPM implements IMakeBookingPM{

	Logger log = Logger.getLogger(MakeBookingPM.class); 
	
	/**
	 * Implementation of a business process to make a booking
	 */
	public int makeBooking(Booking b) {
		log.info(this.getClass() + " : Entering method makeBooking()");
		UMOEventContext context = RequestContext.getEventContext();
		try {
			/* ************************************* */
			/* Business Process for making a Booking */
			/* ************************************* */
			// First, retrieve userIds for every customer inside to booking object
			// 1.) Fetch all users from customer administration
			// 2.) Try to detect all new users (users which are not already registered)
			// 3.) Enter every new user into the customer administration
			// 4.) Fetch all users again and get the userIds
			// 5.) Finally update the booking object and make the booking
			// 6.) Finally make an entry in the booking user's history
			
			MuleClient client = new MuleClient();
			// *******
			// * 1.) *
			// *******
			log.info(this.getClass() + " : Getting all users");
			UMOMessage result1 = client.send("axis:http://localhost:8081/axis/services/CustomerAdministration?method=getUsers","",null);
			User[] users = (User[])result1.getPayload();
			// Cache all users by their first and last name (bad!)
			Map userCache = new HashMap();
			log.info(this.getClass() + " : Caching all users");
			for (int i = 0; i < users.length; i++)
			{
				userCache.put(((User)users[i]).getFirstName() + " " + ((User)users[i]).getName(),((User)users[i]).getUserId());
			}
			
            // *******
			// * 2.) *
			// *******
			log.info(this.getClass() + " : Try to retrieve all ids");
			List newUsers = new ArrayList();         // Users to enter into the club database 
			// First the bookingUser
			String bookingUserName = b.getBookingUser().getFirstName() + " " + b.getBookingUser().getName();
			Object userId = (Object)userCache.get(bookingUserName);
			if (userId == null)
			{
				log.info(this.getClass() + " : The booking user " + b.getBookingUser().getFirstName() + " " + b.getBookingUser().getName() + " is not registered in the club.");
				newUsers.add(b.getBookingUser());
			}
			// Now check the other users of the booking
			for (Iterator itor = b.getUsers().iterator(); itor.hasNext(); )
			{
				User u = (User)itor.next();
				userId = (Object)userCache.get(u.getFirstName() + " " + u.getName());
				if (!((u.getFirstName() + " " + u.getName()).equals(bookingUserName))) // Skip if the bookingUser exists twice in the Booking object
				{
					if (userId == null)
					{
						log.info(this.getClass() + " : Detected new user " + u.getFirstName() + " " + u.getName());
						newUsers.add(u);
					} else log.info(this.getClass() + " : User " + u.getFirstName() + " " + u.getName() + " is familiar to the club");
				}
			}
			
            // *******
			// * 3.) *
			// *******
			if (newUsers.size() > 0) log.info(this.getClass() + " : Entering new users into the club database");
			for (Iterator itor = newUsers.iterator(); itor.hasNext();)
			{
				User u = (User)itor.next();
				log.info(this.getClass() + " : Entering " + u.getFirstName() + " " + u.getName());
				UMOMessage result2 = client.send("axis:http://localhost:8081/axis/services/CustomerAdministration?method=enterNewUser",u,null);
				Integer ok = (Integer)result2.getPayload();
				if (ok.intValue() > 0) log.info(this.getClass() + " : Successfully");
				else log.info(this.getClass() + " : Error entering user " + u.getFirstName() + " " + u.getFirstName());
			}
			
            // *******
			// * 4.) *
			// *******
			log.info(this.getClass() + " : Fetching all users again");
			result1 = client.send("axis:http://localhost:8081/axis/services/CustomerAdministration?method=getUsers","",null);
			users = (User[])result1.getPayload();
			log.info(this.getClass() + " : Caching all users again");
			userCache = new HashMap();
			
			List newUsers4Booking = new ArrayList(); // all users from the booking updated and ready to be reentered in to the Booking object
			for (int i = 0; i < users.length; i++)
			{
				userCache.put(((User)users[i]).getFirstName() + " " + ((User)users[i]).getName(),((User)users[i]).getUserId());
			}
			// Finally retrieve all ids for the users
			// First the booking user
			String userId4BookingUser = (String)userCache.get(bookingUserName);
			User bu = b.getBookingUser();
			bu.setUserId(userId4BookingUser);
			b.setBookingUser(bu);
			for (Iterator itor = b.getUsers().iterator(); itor.hasNext(); )
			{
				User u = (User)itor.next();
				String userName = u.getFirstName() + " " + u.getName();
				userId = userCache.get(userName);
				u.setUserId((String)userId);
				newUsers4Booking.add(u);
			}
			
            // *******
			// * 5.) *
			// *******			
			b.setUsers(newUsers4Booking);
			log.info(this.getClass() + " : Making the booking");
			//UMOMessage result = context.sendEvent(b);
            //MuleClient client = new MuleClient();
			UMOMessage result = client.send("axis:http://localhost:8081/axis/services/VacancyManagement?method=makeBooking",b,null);
			Integer ok = (Integer)result.getPayload();
			if (ok.intValue() > 0) log.info(this.getClass() + " : Successfully made a Booking");
			  else log.info(this.getClass() + " : Booking process was not successfull!"); 
			
			
			// *******
			// * 6.) *
			// *******
			log.info(this.getClass() + " : Making a history entry");
			HistoryEntry entry = new HistoryEntry();
			entry.setEntryDate(new Date());
			entry.setUserId(b.getBookingUser().getUserId());
			User u = b.getBookingUser();
			entry.setEntryText(u.getFirstName() + " " + u.getName() + " made a booking for room " + b.getRoomsIds().get(0));
			entry.setEntryTypeDesc("BOOKING");
			result = client.send("axis:http://localhost:8081/axis/services/CustomerAdministration?method=addHistoryEntry",entry,null);
			ok = (Integer)result.getPayload();
			if (ok.intValue() > 0) log.info(this.getClass() + " : Successfully entered a history entry");
			  else log.info(this.getClass() + " : Could not enter a history entry!");
			context.setStopFurtherProcessing(true);
			return ok.intValue();
		} catch (UMOException e) {
			e.printStackTrace();
		}
		return -1;
	}
	
}
