/**
 * PartnerDispatchAction.java
 * Created on May 8, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.web.actions.partner;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;

import com.tandbergtv.watchpoint.pmm.entities.ContainerType;
import com.tandbergtv.watchpoint.pmm.entities.IContainer;
import com.tandbergtv.watchpoint.pmm.entities.Job;
import com.tandbergtv.watchpoint.pmm.entities.Partner;
import com.tandbergtv.watchpoint.pmm.entities.PartnerContact;
import com.tandbergtv.watchpoint.pmm.entities.PartnerType;
import com.tandbergtv.watchpoint.pmm.entities.PitchFrequency;
import com.tandbergtv.watchpoint.pmm.entities.Schedule;
import com.tandbergtv.watchpoint.pmm.entities.Service;
import com.tandbergtv.watchpoint.pmm.job.IJobManager;
import com.tandbergtv.watchpoint.pmm.job.JobManager;
import com.tandbergtv.watchpoint.pmm.partner.IPartnerManagement;
import com.tandbergtv.watchpoint.pmm.partner.PartnerManager;
import com.tandbergtv.watchpoint.pmm.service.IServiceManagement;
import com.tandbergtv.watchpoint.pmm.service.ServiceManager;
import com.tandbergtv.watchpoint.pmm.util.ContextManager;
import com.tandbergtv.watchpoint.pmm.util.IContextManager;
import com.tandbergtv.watchpoint.pmm.web.formbeans.job.JobForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.job.JobListForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.partner.PartnerForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.partner.PartnerListForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.service.ServiceForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.service.ServiceListForm;
import com.tandbergtv.watchpoint.pmm.web.schedule.ScheduleForm;
import com.tandbergtv.watchpoint.pmm.web.schedule.ScheduleListForm;
import com.tandbergtv.watchpoint.pmm.web.util.CommonUtils;
import com.tandbergtv.watchpoint.pmm.web.util.GUISearchHelper;
import com.tandbergtv.watchpoint.pmm.web.util.PMMTableConfigHelper;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.core.service.cache.ICacheService;
import com.tandbergtv.workflow.util.SearchCriteria;
import com.tandbergtv.workflow.web.common.StaticCodes;
import com.tandbergtv.workflow.web.formbeans.PaginationAndSortingForm;
import com.tandbergtv.workflow.web.util.ExportUtility;

/**
 * @author Vlada Jakobac
 * 
 */
public class PartnerDispatchAction extends DispatchAction {

	private static final String PARTNERS = "partners";

	private static final Logger logger = Logger
			.getLogger(PartnerDispatchAction.class);

	private static final String FORWARD_POST_CREATE_PARTNER = "postCreatePartner";

	private static final String FORWARD_PARTNER_DETAILS = "partnerDetails";

	private static final String JOBS = "jobs";

	private static final String SCHEDULES = "schedules";

	private static String CONTAINER_CACHE_SERVICE_NAME = "Container Cache";
	
	private static final String DISPLAY_MESSAGE = "partner.update.messages";
	
	private static final String DISPLAY_ERRORS = "partner.update.errors";

	private IPartnerManagement partnerManager;

	public PartnerDispatchAction() {
		super();
		this.partnerManager = PartnerManager.getInstance();
	}

	public ActionForward createPartnerSetup(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		return actionMapping.findForward("createPartner");
	}

	public ActionForward createPartner(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		PartnerForm partnerForm = (PartnerForm) actionForm;

		Partner partner = new Partner();

		// Prepare a Partner object from the PartnerForm object
		partner = preparePartner(partnerForm, partner);

		partner = partnerManager.createPartner(partner);
		logger.debug("new partner id=" + partner.getId());
		partnerForm.setId(String.valueOf(partner.getId()));
		partnerForm.setContextId(partner.getContainerContextId());

		// Set the attribute for the post message after creation of a
		// Partner
		request.setAttribute(StaticCodes.PARTNER_CREATED,
				StaticCodes.PARTNER_CREATED);

		// Set the PartnerForm in the Request Scope
		request.setAttribute(StaticCodes.OUTPUT_DATA, partnerForm);

		return actionMapping.findForward(FORWARD_POST_CREATE_PARTNER);

	}

	private Partner preparePartner(PartnerForm partnerForm, Partner partner) throws Exception {
		logger.debug(this + "preparePartner()---->Starting");

		// Setting Partner properties
		partner.setName(partnerForm.getName());

		partner.setType(PartnerType.getById(Long.parseLong(partnerForm
				.getTypeId())));

		partner.setProviderId(partnerForm.getProviderId());

		PartnerContact contact = createPartnerContact(partnerForm, partner);
		partner.setContact(contact);

		if (partner.getType().equals(PartnerType.DISTRIBUTION))	{
			logger.debug("partnerForm.getDefaultPitchFreqWeeks()="+partnerForm.getDefaultPitchFreqWeeks()+".");
			if (partnerForm.getDefaultPitchFreqWeeks() != null && !partnerForm.getDefaultPitchFreqWeeks().trim().equals("")){
				PitchFrequency defaultPitchFreq = createDefaultPitchFrequency(
						partnerForm, partner);
				partner.setDefaultPitchFrequency(defaultPitchFreq);
			}
		} 
		partner.setNotes(partnerForm.getNotes());
		
		partner.setLookupKey(partnerForm.getLookupKey());

		IContextManager ctxMgr = ContextManager.getInstance();
		partner.setContext(ctxMgr.getContext(partnerForm.getContextId()));

		return partner;
	}

	private PitchFrequency createDefaultPitchFrequency(PartnerForm partnerForm,
			Partner partner) {
		PitchFrequency defaultPitchFreq = new PitchFrequency();
		defaultPitchFreq.setId(partnerForm.getDefPitchFreqId());
		defaultPitchFreq.setDistributionPartner(partner);
		defaultPitchFreq.setPitchDay(Integer.parseInt(partnerForm
				.getDefaultPitchFreqDayId()));
		defaultPitchFreq.setWeeksBetweenPitch(Integer.parseInt(partnerForm
				.getDefaultPitchFreqWeeks()));
		return defaultPitchFreq;
	}
	
	private PartnerContact createPartnerContact(PartnerForm partnerForm,
			Partner partner) {
		PartnerContact contact = new PartnerContact();
		contact.setId(partnerForm.getContactId());
		contact.setEmail(partnerForm.getEmail());
		contact.setFirstName(partnerForm.getFirstName());
		contact.setLastName(partnerForm.getLastName());
		contact.setPartner(partner);
		return contact;
	}

	public ActionForward getPartnersView(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		boolean exportFlag = false;
        exportFlag = ((request.getParameter("exportData") != null) && (request.getParameter("exportData").toString().equals("export") ))?true : false;

		PartnerListForm partnerListForm = (PartnerListForm) actionForm;
		SearchCriteria searchCriteria = partnerListForm.getSearchCriteria();

		logger.debug("The Search Criteria--->" + searchCriteria);

		List<PartnerForm> partners = new ArrayList<PartnerForm>();

		if(exportFlag) {
			searchCriteria.setStartingRecordNumber(0);
			searchCriteria.setRecordsCount(Integer.MAX_VALUE);
		}
		List<Partner> lsPartners = partnerManager
				.getPartnersBySearchCriteria(searchCriteria);
		// Iterating thru the list of partners and making a collection of
		// PartnerForm objects
		PartnerForm partnerForm = null;
		for (Partner partner : lsPartners) {
			logger.debug("Partner Name is---->" + partner.getName());
			
			partnerForm = new PartnerForm();

			// Preparing the PartnerForm object from the Partner
			partnerForm = preparePartnerForm(partner, partnerForm);

			// Putting into a collection
			partners.add(partnerForm);
		}

		// Get the total number of active Partners
		int iTotalRecords = partnerManager.getTotalActivePartnerCount();
		
		logger.debug("Total number of records -->" + iTotalRecords);
		partnerListForm.setTotalRecords(iTotalRecords);

		// put the collection into Partnerlistform
		partnerListForm.setPartnerList(partners);

		//Export Data to Excel
		if(exportFlag) {
			
	    	ExportUtility exportUtility = new ExportUtility();	  	    	 
	    	exportUtility.exportDataToExcel(request, response, partnerListForm,partners, PMMTableConfigHelper.getTableConfigFile());
	    	 
	    	 return null;
	     }
		// Assign to parent reference
		PaginationAndSortingForm paginationAndSortingForm = partnerListForm;

		// Search Criteria
		request.setAttribute(StaticCodes.SEARCH_CRITERIA,
				paginationAndSortingForm);

		return actionMapping.findForward(PARTNERS);
	}

	/**
	 * This method populates the data from the Partner Object to PartnerForm
	 * which is used for the UI presentation
	 * 
	 * @param partner
	 *            Partner instance
	 * @param partnerForm
	 *            PartnerForm instance
	 * @return PartnerForm instance
	 */
	private PartnerForm preparePartnerForm(Partner partner,
			PartnerForm partnerForm) {

		// Setting all the Partner Properties into the formbean
		partnerForm.setId(String.valueOf(partner.getId()));
		partnerForm.setName(partner.getName());

		PartnerType partnerType = partner.getType();
		partnerForm.setTypeName(partnerType.name());
		partnerForm.setTypeId(String.valueOf(partnerType.getTypeId()));
		partnerForm.setProviderId(partner.getProviderId());

		PartnerContact contact = partner.getContact();
		partnerForm.setEmail(contact.getEmail());
		partnerForm.setFirstName(contact.getFirstName());
		partnerForm.setLastName(contact.getLastName());
		partnerForm.setContactId(contact.getId());

		partnerForm.setNotes(partner.getNotes());
		partnerForm.setLookupKey(partner.getLookupKey());

		partnerForm.setContextId(partner.getContext().getId());

		
		PitchFrequency defaultPitchFrequency = partner.getDefaultPitchFrequency();
		if (defaultPitchFrequency != null){//there is some record, could be stale if it is for the source partner
			//set the ID, even if it's a source partner
			partnerForm.setDefPitchFreqId(defaultPitchFrequency.getId());
			if (partner.getType().equals(PartnerType.DISTRIBUTION))	{
				partnerForm.setDefaultPitchFreqWeeks(Integer.toString(defaultPitchFrequency.getWeeksBetweenPitch()));
				partnerForm.setDefaultPitchFreqDayId(Integer.toString(defaultPitchFrequency.getPitchDay()));
			}
			logger.debug("defaultPitchFrequency.getId()="+defaultPitchFrequency.getId());
		} 
		
		logger.debug("partner: " + partner.getId() + ", partnerType: "
				+ partnerType.name() + ", " + partnerType.getTypeId());
		return partnerForm;
	}

	public ActionForward deletePartners(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		PartnerForm partnerForm = (PartnerForm) actionForm;
		String strPartnerIds[] = partnerForm.getSelectedPartners();
		
		ActionMessages messages = new ActionMessages();
		
		for (int i = 0; i < strPartnerIds.length; i++) {
			try {
				boolean isDeleted = partnerManager.deletePartner(Long.parseLong(strPartnerIds[i]));
				if (isDeleted){
					messages.add(StaticCodes.INFO_MESSAGE, new ActionMessage(DISPLAY_MESSAGE,
								"Partner [" +strPartnerIds[i]+ "] deleted successfully."));
				} else {
					messages.add(StaticCodes.INFO_ERROR, new ActionMessage(DISPLAY_ERRORS,
							"Partner [" +strPartnerIds[i]+ "] cannot be deleted."));
				}
				
			} catch (Exception exception) {
				messages.add(StaticCodes.INFO_ERROR, new ActionMessage(DISPLAY_ERRORS,
						exception.getMessage()));
				
			}
		}

		saveErrors(request, messages);
		saveMessages(request, messages);
		
		return actionMapping.findForward(PARTNERS);
	}

	@SuppressWarnings("unchecked")
	public ActionForward getPartnerDetails(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		logger.debug("Starting---->");
		Long contextId = null;

		PartnerForm partnerForm = (PartnerForm) actionForm;

		contextId = partnerForm.getContextId();
		logger.debug("Partner contextId------->" + contextId);
		Long partnerId = null;
		
		if (contextId != null && contextId != 0) {
			//obtain partnerId from contextId
			ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
				.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
			IContainer container = containerCache.get(contextId);
			partnerId = ((Partner)container).getId();
		} else if (partnerForm.getId() != null) {
			partnerId = Long.valueOf(partnerForm.getId());
		}
		
		logger.debug("Partner Id------->" + partnerId);
		
		Partner partner = partnerManager.getPartner(partnerId);

		// Preparing PartnerForm Object from the Partner Object
		partnerForm = preparePartnerForm(partner, partnerForm);
		

		request.setAttribute(StaticCodes.MODIFYPARTNER_TAB_ITEM,
				StaticCodes.MODIFYPARTNER_TAB_ITEM);

		request.setAttribute(StaticCodes.OUTPUT_DATA, partnerForm);
		logger.debug("Ending---->");
		return actionMapping.findForward(FORWARD_PARTNER_DETAILS);
	}

	public ActionForward updatePartner(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		try {
			PartnerForm partnerForm = (PartnerForm) actionForm;

			Partner partner = partnerManager.getPartner(Long.parseLong(partnerForm.getId())); 

			// Prepare a Partner object from the PartnerForm object partner =
			preparePartner(partnerForm, partner);
			partner = partnerManager.updatePartner(partner);
			partnerForm.setId(String.valueOf(partner.getId()));

			// Set the attribute for the post message after creation of a
			// Partner
			request.setAttribute(StaticCodes.PARTNER_UPDATED,
					StaticCodes.PARTNER_UPDATED);

			// Set the partnerForm in the Request Scope

			request.setAttribute(StaticCodes.OUTPUT_DATA, partnerForm);
		} catch (Exception validationException) {
			// to do
		}

		return actionMapping.findForward(FORWARD_POST_CREATE_PARTNER);
	}

	@SuppressWarnings("unchecked")
	public ActionForward getJobsForPartner(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		JobListForm jobListForm = (JobListForm) actionForm;
		String contextId = jobListForm.getContextId();
		// SearchCriteria searchCriteria = jobListForm.getSearchCriteria();

		logger.debug("Partner Context id --->" + contextId);

		List<JobForm> jobForms = new ArrayList<JobForm>();

		IJobManager jobManager = JobManager.getInstance();
		List<Job> lsJobs = jobManager.getAllJobs(Long.parseLong(contextId));

		JobForm jobForm = null;
		for (Job job : lsJobs) {
			logger.debug("Job Name is---->" + job.getName());
			jobForm = new JobForm();
			jobForm = prepareJobForm(job, jobForm);
			jobForms.add(jobForm);
		}

		// Get the total number of active Jobs
		int iTotalRecords;
		if (lsJobs != null)
			iTotalRecords = lsJobs.size();
		else
			iTotalRecords = 0;
		logger.debug("Total number of records -->" + iTotalRecords);
		jobListForm.setTotalRecords(iTotalRecords);

		ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
				.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
		IContainer container = containerCache.get(new Long(contextId));
		ContainerType containerType = container.getContainerType();
		if (containerType == ContainerType.PARTNER) {// it must be!!!
			String partnerName = ((Partner)container).getName();
			jobListForm.setName(partnerName);
			PartnerType partnerType = ((Partner) container).getType();
			if (partnerType == PartnerType.SELF) {
				jobListForm.setEntityType(partnerType.toString());
			} else
				jobListForm.setEntityType(container.getContainerType()
						.toString());
		} else {
			jobListForm.setEntityType(container.getContainerType().toString());
		}

		jobListForm.setJobList(jobForms);
		request.setAttribute(StaticCodes.SEARCH_CRITERIA,
				jobListForm);
		request.setAttribute(StaticCodes.MODIFYPARTNER_TAB_ITEM,
				StaticCodes.MODIFYPARTNER_TAB_ITEM);

		return actionMapping.findForward(JOBS);
	}

	private JobForm prepareJobForm(Job job, JobForm jobForm) {

		jobForm.setId(job.getId());
		jobForm.setName(job.getName());
		jobForm.setSelectedTemplate(job.getTemplateName());
		jobForm.setSelectedPriority(job.getPriority().name());
		jobForm.setScheduleRule(job.getScheduleRuleString());
		if ((job.isTitleAssociated())){
			jobForm.setIsAssociatedWithTitles("YES");
		} else {
			jobForm.setIsAssociatedWithTitles("NO");
		}

		return jobForm;
	}

	@SuppressWarnings("unchecked")
	public ActionForward getCurrentSchedulesForPartner(
			ActionMapping actionMapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		ScheduleListForm scheduleListForm = (ScheduleListForm) actionForm;
		String contextId = scheduleListForm.getContextId();

		logger.debug("Partner Context id --->" + contextId);

		List<ScheduleForm> scheduleForms = new ArrayList<ScheduleForm>();
		Collection<Schedule> lsSchedules = null;
		ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
				.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
		IContainer container = containerCache.get(new Long(contextId));
		if (container == null)
			logger.debug("container is null for contextId=" + contextId);

		ContainerType containerType = container.getContainerType();
		if (containerType == ContainerType.PARTNER) {// it must be!!!
			Partner partner = (Partner) container;
			String partnerName = partner.getName();
			scheduleListForm.setName(partnerName);
			Long partnerId = partner.getId();
			scheduleListForm.setId(partnerId.toString());
			PartnerType partnerType = ((Partner) container).getType();
			if (partnerType == PartnerType.SOURCE) {
				lsSchedules = GUISearchHelper.getCurrentPlanners(partnerId);
				scheduleListForm.setTypeName("SOURCE");
			} else if (partnerType == PartnerType.DISTRIBUTION) {
				lsSchedules = GUISearchHelper.getCurrentPitchSchedules(new Long(contextId));
				scheduleListForm.setTypeName("DISTRIBUTION");
			} else {//it's SELF partner
				scheduleListForm.setTypeName("SELF");
			}
		}

		ScheduleForm scheduleForm = null;
		int iTotalRecords;
		if (lsSchedules != null){
			for (Schedule schedule : lsSchedules) {
				logger.debug("Schedule id is---->" + schedule.getId());
				scheduleForm = new ScheduleForm();
				scheduleForm = prepareScheduleForm(schedule, scheduleForm);
				scheduleForms.add(scheduleForm);
			}
			iTotalRecords = lsSchedules.size();
		}
		else
			iTotalRecords = 0;
		logger.debug("Total number of records -->" + iTotalRecords);
		scheduleListForm.setTotalRecords(iTotalRecords);

		scheduleListForm.setScheduleList(scheduleForms);
		request.setAttribute(StaticCodes.SEARCH_CRITERIA,
				scheduleListForm);
		request.setAttribute(StaticCodes.MODIFYPARTNER_TAB_ITEM,
				StaticCodes.MODIFYPARTNER_TAB_ITEM);

		return actionMapping.findForward(SCHEDULES);
	}

	private ScheduleForm prepareScheduleForm(Schedule schedule,
			ScheduleForm scheduleForm) {

		scheduleForm.setScheduleId(Long.toString(schedule.getId()));
		scheduleForm.setStatus(schedule.getStatus().name());
		scheduleForm.setDate(CommonUtils.formatDate(schedule.getDate()));
		return scheduleForm;
	}

	@SuppressWarnings("unchecked")
	public ActionForward getServicesForPartner(
			ActionMapping actionMapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
	
		ServiceListForm serviceListForm = (ServiceListForm) actionForm;
		String contextId = serviceListForm.getContextId();
		
		List<ServiceForm> serviceForms = new ArrayList<ServiceForm>();

		IServiceManagement serviceManager = ServiceManager.getInstance();
		Set<Service> lsServices = serviceManager.getAllServicesAssociatedWithPartner(Long.parseLong(contextId));
		
		ServiceForm serviceForm = null;
		for (Service service : lsServices) {
			serviceForm = new ServiceForm();
			serviceForm = prepareServiceForm(service, serviceForm);
			serviceForms.add(serviceForm);
		}

		int iTotalRecords;
		if (lsServices != null)
			iTotalRecords = lsServices.size();
		else
			iTotalRecords = 0;
		logger.debug("Total number of records -->" + iTotalRecords);
		serviceListForm.setTotalRecords(iTotalRecords);
		
		ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
			.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
		IContainer container = containerCache.get(new Long(contextId));
		ContainerType containerType = container.getContainerType();
		if (containerType == ContainerType.PARTNER) {// it must be!!!
			String partnerName = ((Partner)container).getName();
			serviceListForm.setName(partnerName);
			PartnerType partnerType = ((Partner) container).getType();
			if (partnerType == PartnerType.SOURCE) {
				serviceListForm.setTypeName("SOURCE");
			} else if (partnerType == PartnerType.DISTRIBUTION) {
				serviceListForm.setTypeName("DISTRIBUTION");
			} else {//it's SELF partner
				serviceListForm.setTypeName("SELF");
			}
		} 
		serviceListForm.setServiceList(serviceForms);
		request.setAttribute(StaticCodes.SEARCH_CRITERIA,
				serviceListForm);
		request.setAttribute(StaticCodes.MODIFYPARTNER_TAB_ITEM,
				StaticCodes.MODIFYPARTNER_TAB_ITEM);
		
		return actionMapping.findForward("services");
	}

	private ServiceForm prepareServiceForm(Service service,
			ServiceForm serviceForm) {
		serviceForm.setId(Long.toString(service.getId()));
		serviceForm.setName(service.getName());
		serviceForm.setDescription(service.getDescription());
		
		return serviceForm;
	}
	
}
