package gov.va.med.esr.webservices.client.vadir;

import gov.va.schema.militaryhistory.MilitaryHistory;
import gov.va.schema.militaryhistory.ServicePeriod;
import gov.va.schema.militaryhistoryservice.GetMilitaryHistory;
import gov.va.schema.militaryhistoryservice.GetMilitaryHistoryResponse;
import gov.va.schema.militaryhistoryservice.SearchCriteria;

import java.util.Date;

import javax.xml.datatype.DatatypeFactory;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.apache.log4j.Logger;

/**
 * Client for JAX-WS VADIR Web Service.
 * 
 * @author DNS   barryc
 */
@Repository(value = "vadirWSClient")
public class VadirWSClientImpl implements VadirWSClient {

	
	private static final Logger logger = Logger.getLogger(VadirWSClientImpl.class);
	
	@Autowired
	private WebServiceTemplate vadirWebServiceTemplate;
	
	@Autowired
	private EMISMilitaryInformationServiceClient eMISService;
	
	private int throttleCount = -1;
	private int throttleStartTime = 0;
	private int throttleEndTime = 0;
	
	public int getThrottleCount() {
		return throttleCount;
	}

	public void setThrottleCount(int throttleCount) {
		this.throttleCount = throttleCount;
	}

	public int getThrottleEndTime() {
		return throttleEndTime;
	}

	public void setThrottleEndTime(int throttleEndTime) {
		this.throttleEndTime = throttleEndTime;
	}

	public int getThrottleStartTime() {
		return throttleStartTime;
	}

	public void setThrottleStartTime(int throttleStartTime) {
		this.throttleStartTime = throttleStartTime;
	}

	public MilitaryHistory getMilitaryHistory(SearchCriteria searchCriteria)
			throws WebServiceClientException {
		GetMilitaryHistory request = new GetMilitaryHistory();
		request.setCriteria(searchCriteria);

		boolean requireThrottle = VadirThrottleController.requireThrottle();
		
		if ( requireThrottle) {
			VadirThrottleController.increaseCount();
		}
		
		Object resultObj = null;
		
		
		Date startTime = new Date();
		try{
			String isEMISProviderInUse = VadirThrottleController.getIsEMISProviderInUse();
			logger.debug("isEMISProviderInUse="+isEMISProviderInUse);
			if (VadirThrottleController.NO.equalsIgnoreCase(isEMISProviderInUse) 
					|| VadirThrottleController.BOTH.equalsIgnoreCase(isEMISProviderInUse)) {
				logger.debug("isEMISProviderInUse is No or Both");
				String icn = (request != null && request.getCriteria() != null) ? request.getCriteria().getICN() : null;
				logger.debug("icn="+icn);
		        if (icn != null) {		        	
			        String str[] = StringUtils.split(icn, EMISMilitaryInformationServiceClient.ICN_DELIMITER);
			        if (str != null && str.length == 2) {
			        	icn = str[0];
			        	request.getCriteria().setICN(icn);
			        	logger.debug("icn updated="+icn);
			        }
			        logger.debug("invoking Vadir call");			        
					resultObj = vadirWebServiceTemplate.marshalSendAndReceive(request);
					logger.debug("received response");
					eMISService.log("Vadir request/response", request, resultObj);
		        }
			}
			
			if (VadirThrottleController.YES.equalsIgnoreCase(isEMISProviderInUse) 
					|| VadirThrottleController.BOTH.equalsIgnoreCase(isEMISProviderInUse)) {
				logger.debug("invoking eMis call for isEMISProviderInUse as Yes or Both");
				String icn = (request != null && request.getCriteria() != null) ? request.getCriteria().getICN() : null;
				logger.debug("icn="+icn);
				/** Testing msds war without any change to ESR
				if (icn != null && icn.indexOf("1008693885V036764") != -1) {
					String edipi = "6001010086";
					logger.debug("edipi="+edipi);
					request.getCriteria().setICN(icn+"^"+edipi);
				} else if (icn != null && icn.indexOf("1008693879V857990") != -1) {
					String edipi = "6001010046";
					logger.debug("edipi="+edipi);
					request.getCriteria().setICN(icn+"^"+edipi);
				}
				*/
				resultObj = eMISService.getMilitaryHistory(request);
				logger.debug("received response");
				eMISService.log("eMIS request/response", request, resultObj);
			}
			
		}catch(WebServiceClientException e) {
			e.printStackTrace();
			throw e;
		}catch(Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		finally {
			if ( requireThrottle) {
				VadirThrottleController.decreseCount();
			}
			Date endTime = new Date();
			logger.debug("Vadir Call Start and End Time :" + startTime + "\t" + endTime);
		}
		
		if (resultObj instanceof GetMilitaryHistoryResponse == false)
			throw new RuntimeException(
					"Unexpected type returned from web service: "
							+ resultObj.getClass());

		GetMilitaryHistoryResponse response = (GetMilitaryHistoryResponse) resultObj;
		return response.getGetMilitaryHistoryReturn();
	}


	private void log(String tag, Object request, Object response) {
		logger.debug(tag);
		if (request instanceof GetMilitaryHistory) {
			logger.debug(ToStringBuilder.reflectionToString((GetMilitaryHistory)request, ToStringStyle.MULTI_LINE_STYLE));
		}
		if (response instanceof GetMilitaryHistoryResponse) {
			logger.debug(ToStringBuilder.reflectionToString((GetMilitaryHistoryResponse)response, ToStringStyle.MULTI_LINE_STYLE));
		}
	}
	
	public static void main(String[] args) throws Exception {
		String cp = System.getProperty( "java.class.path" );		
		System.out.println("CP :" + cp);
		
		//ApplicationContext appContext = new ClassPathXmlApplicationContext(
		//		"applicationContext-vadir.xml");
		
		ApplicationContext appContext = new FileSystemXmlApplicationContext("C:\\dev\\dev-projects\\es\\esr\\maint\\SM_HECMS_Galaxy_Mars_Dev_rtc\\HECMS_websrv\\src\\vadir\\resources\\spring\\applicationContext-vadir.xml");
		System.setProperty("vadir.throttle.starttime", "0820");
		System.setProperty("vadir.throttle.endtime", "1730");
		System.setProperty("vadir.throttle.count", "3");
		
		
		for ( int i=0; i< 3 ; i++ ) {
			VadirClientThread th = new VadirClientThread();
			th.setThreadNumber(i);
			th.setApplicationContext(appContext);
			th.start();
		}
		
		/*
		VadirWSClientImpl client = (VadirWSClientImpl) appContext
				.getBean("vadirWSClient");
				
		DatatypeFactory dtf = DatatypeFactory.newInstance();
		
		System.setProperty("vadir.throttle.starttime", "0820");
		System.setProperty("vadir.throttle.endtime", "1730");
		System.setProperty("vadir.throttle.count", "10");
		
		try {
			SearchCriteria sc = new SearchCriteria();
			sc.setSSN("140663830");
			sc.setLastName("MCKANE");
			sc.setDateOfBirth(dtf.newXMLGregorianCalendar("1959-01-10"));
			sc.setICN("1008693885V036764");
			sc.setGender("M");
			MilitaryHistory mh = client.getMilitaryHistory(sc);

			if (mh == null) {
				System.out.println("No results found.");
			} else {
				//System.out.println(ToStringBuilder.reflectionToString(mh,
						//ToStringStyle.MULTI_LINE_STYLE));
				System.out.println("\nService Periods:");
				for (ServicePeriod period : mh.getVADIR().getServicePeriods()) {
					System.out.println("Period="+period);
					//ToStringBuilder.reflectionToString(
							//period, ToStringStyle.MULTI_LINE_STYLE));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		*/
	}
	
	
	public void afterPropertiesSet() {
		logger.debug("Testing*******************");
		//System.out.println("Testing*******************");
	}
	
	
	/**
	static
    {
		VadirWSClientImpl client = (VadirWSClientImpl) appContext
		.getBean("vadirWSClient");
		
		vadirWSClient.setThrottleCount(VadirThrottleController.getThrottleCount());
		vadirWSClient.setThrottleStartTime(Integer.parseInt(VadirThrottleController.getThrottleStartTime()));
		vadirWSClient.setThrottleEndTime(Integer.parseInt(VadirThrottleController.getThrottleEndTime()));
		
    }
	**/

}
