package com.ejie.ab61.tramita.services;

import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab61.clientesWS.pid.W43DfDocument;
import com.ejie.ab61.clientesWS.pid.W43DfGETDocument;
import com.ejie.ab61.clientesWS.pid.W43DfPIDInterface;
import com.ejie.ab61.clientesWS.pid.W43DfPIDService;
import com.ejie.ab61.clientesWS.pid.W43DfWSFault;

/**
 * PidServiceImpl Clase que implementa la llamada al cliente del PID
 *
 *  
 */
@Service(value = "PidServiceImpl")
public class PidServiceImpl implements PidService {

	private static final Logger logger = LoggerFactory.getLogger(PidServiceImpl.class);

	@Autowired()
	private Properties appConfiguration;

	private W43DfPIDService service;

	private static final QName qname = new QName("com/ejie/documents/xml", "w43dfPIDService");

	/**
	 * getDocument
	 *
	 * @param getDocument
	 *            W43DfGETDocument
	 * @return W43DfDocument
	 * @throws W43DfWSFault
	 */
	@Override
	public W43DfDocument getDocument(W43DfGETDocument getDocument) throws W43DfWSFault {
		return this.getW43DfPIDInterfacePort().getDocument(getDocument);
	}

	/**
	 * addDocument
	 *
	 * @param newDocument
	 *            W43DfDocument
	 * @return String
	 * @throws W43DfWSFault
	 */
	@Override
	public String addDocument(W43DfDocument newDocument) throws W43DfWSFault {
		return this.getW43DfPIDInterfacePort().addDocument(newDocument);
	}

	/**
	 * deleteDocument
	 *
	 * @param documentId
	 *            String
	 * @throws W43DfWSFault
	 */
	@Override
	public void deleteDocument(String documentId) throws W43DfWSFault {
		this.getW43DfPIDInterfacePort().deleteDocument(documentId);
	}

	/**
	 * modifyDocument
	 *
	 * @param putDocument
	 *            W43DfDocument
	 * @throws W43DfWSFault
	 */
	@Override
	public void modifyDocument(W43DfDocument putDocument) throws W43DfWSFault {
		this.getW43DfPIDInterfacePort().modifyDocument(putDocument);
	}

	/**
	 * iniciarW43DfPIDServiceService
	 */
	public void iniciarW43DfPIDServiceService() {
		this.getW43DfPIDInterfacePort(false);
	}

	// INICAMOS PORT SERVICE

	/**
	 * getW43DfPIDInterfacePort
	 *
	 * @return W43DfPIDInterface
	 */
	private W43DfPIDInterface getW43DfPIDInterfacePort() {
		return this.getW43DfPIDInterfacePort(true);
	}

	/**
	 * getW43DfPIDInterfacePort
	 *
	 * @param getPort
	 *            boolean
	 * @return W43DfPIDInterface
	 */
	private W43DfPIDInterface getW43DfPIDInterfacePort(boolean getPort) {
		try {
			if (this.service == null) {
				logger.info("<<<<<<<<<<<<<<<<<<< INICIANDO SERVICE W43DfPIDService >>>>>>>>>>>>>>>>>>>>>>>>>>>>");
				service = new W43DfPIDService(new URL(appConfiguration.getProperty("URL_PID")), qname);
				service.setHandlerResolver(new HandlerResolver() {
					@Override
					public List getHandlerChain(PortInfo portInfo) {
						return Collections.singletonList(new PidServiceHandler());
					}
				});

				logger.info("<<<<<<<<<<<<<<<<<<< INICIADO SERVICE W43DfPIDService >>>>>>>>>>>>>>>>>>>>>>>>>>>>");
			}
			if (getPort) {
				logger.info(
						"<<<<<<<<<<<<<<<<<<< get SERVICE PORT W43DfPIDService inicia llamada WS >>>>>>>>>>>>>>>>>>>>>>>>>>>>");
				W43DfPIDInterface proxy = this.service.getW43DfPIDPort();
				Map<String, Object> ctxt = ((BindingProvider) proxy).getRequestContext();
				ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, appConfiguration.getProperty("URL_PID"));
				return proxy;
			}
		} catch (Exception e) {
			logger.error("Error", e);
			this.service = null;
		}
		return null;
	}
}