package at.gv.egovernment.moa.spss.server.webservice.impl;

import java.util.Collections;

import javax.annotation.Resource;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.gv.egiz.moasig.CreateCMSSignatureRequest;
import at.gv.egiz.moasig.CreateCMSSignatureResponseType;
import at.gv.egiz.moasig.CreatePDFSignatureRequest;
import at.gv.egiz.moasig.CreatePDFSignatureResponseType;
import at.gv.egiz.moasig.CreateXMLSignatureRequest;
import at.gv.egiz.moasig.CreateXMLSignatureResponseType;
import at.gv.egovernment.moa.spss.MOAException;
import at.gv.egovernment.moa.spss.MOASystemException;
import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureCreationInvoker;
import at.gv.egovernment.moa.spss.server.invoke.PDFASInvoker;
import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker;
import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
import at.gv.egovernment.moa.spss.server.webservice.CMSCreateSignatureBinding;
import at.gv.egovernment.moa.spss.server.webservice.PDFCreateSignatureBinding;
import at.gv.egovernment.moa.spss.server.webservice.SignatureCreationService;
import at.gv.egovernment.moa.spss.server.webservice.XMLCreateSignatureBinding;
import at.gv.egovernment.moa.spss.server.webservice.binding.CMSCreateSignatureBindingImpl;
import at.gv.egovernment.moa.spss.server.webservice.binding.PDFCreateSignatureBindingImpl;
import at.gv.egovernment.moa.spss.server.webservice.binding.XMLCreateSignatureBindingImpl;
import at.gv.egovernment.moa.spss.server.xmlbind.CreatePDFRequest;
import at.gv.egovernment.moa.spss.server.xmlbind.CreatePDFRespone;
import at.gv.egovernment.moa.util.StreamUtils;

@WebService(endpointInterface = "at.gv.egovernment.moa.spss.server.webservice.SignatureCreationService", portName = "SignatureCreationService", serviceName = "SignatureCreationService")
public class SignatureCreationServiceImpl implements SignatureCreationService {

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

	@Resource
	private WebServiceContext context;

	private XMLCreateSignatureBinding xmlCreateSignatureBinding;
	private CMSCreateSignatureBinding cmsCreateSignatureBinding;
	private PDFCreateSignatureBinding pdfCreateSignatureBinding;

	public SignatureCreationServiceImpl() {
		this.xmlCreateSignatureBinding = new XMLCreateSignatureBindingImpl();
		this.cmsCreateSignatureBinding = new CMSCreateSignatureBindingImpl();
		this.pdfCreateSignatureBinding = new PDFCreateSignatureBindingImpl();
	}

	@Override
	@WebResult(name = "CreateXMLSignatureResponseType", targetNamespace = "http://reference.e-government.gv.at/namespace/moa/20151109#")
	public CreateXMLSignatureResponseType createXMLSignature(CreateXMLSignatureRequest createXMLSignatureRequest)
			throws Exception {
		logger.info("createXMLSignature start");
		try {
			logger.info("WebServiceContext: {}", context);
			ContextSetupAspect.setupContext(context.getMessageContext(), "createXMLSignature");

			XMLSignatureCreationInvoker invoker = XMLSignatureCreationInvoker.getInstance();

			at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest requestObj;
			at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse responseObj;

			logger.trace(">>> preparsing Request");
			requestObj = this.xmlCreateSignatureBinding.buildXMLRequest(createXMLSignatureRequest);
			logger.trace("<<< preparsed Request");

			logger.trace(">>> creating Signature");
			// invoke the core logic
			responseObj = invoker.createXMLSignature(requestObj, Collections.EMPTY_SET);
			logger.trace("<<< created Signature");

			logger.trace(">>> building Response");
			// map back to XML
			CreateXMLSignatureResponseType response = this.xmlCreateSignatureBinding.buildXMLResponse(responseObj);
			logger.trace("<<< built Response");

			return response;
		} catch (MOAException e) {
			logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:"
					+ System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
			logger.error("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:", e);
			throw new Exception(e.getMessage());
		} catch (Throwable t) {
			MOASystemException e = new MOASystemException("2900", null, t);
			logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:"
					+ System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
			logger.error("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:", e);
			throw new Exception(e.getMessage());
		} finally {
			ContextSetupAspect.cleanContext();
		}
	}

	@Override
	@WebResult(name = "CreateCMSSignatureResponseType", targetNamespace = "http://reference.e-government.gv.at/namespace/moa/20151109#")
	public CreateCMSSignatureResponseType createCMSSignature(CreateCMSSignatureRequest createCMSSignatureRequest)
			throws Exception {
		logger.info("createCMSSignature start");
		try {
			logger.info("WebServiceContext: {}", context);
			ContextSetupAspect.setupContext(context.getMessageContext(), "createCMSSignature");

			CMSSignatureCreationInvoker invoker = CMSSignatureCreationInvoker.getInstance();

			at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureRequest requestObj;
			at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureResponse responseObj;

			logger.trace(">>> preparsing Request");
			requestObj = this.cmsCreateSignatureBinding.buildCMSRequest(createCMSSignatureRequest);
			logger.trace("<<< preparsed Request");

			logger.trace(">>> creating Signature");
			// invoke the core logic
			responseObj = invoker.createCMSSignature(requestObj, Collections.EMPTY_SET);
			logger.trace("<<< created Signature");

			logger.trace(">>> building Response");
			// map back to XML
			CreateCMSSignatureResponseType response = this.cmsCreateSignatureBinding.buildCMSResponse(responseObj);
			logger.trace("<<< built Response");

			return response;

		} catch (MOAException e) {
			logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:"
					+ System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
			logger.error("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:", e);
			throw new Exception(e.getMessage());
		} catch (Throwable t) {
			MOASystemException e = new MOASystemException("2900", null, t);
			logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:"
					+ System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
			logger.error("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:", e);
			throw new Exception(e.getMessage());
		} finally {
			ContextSetupAspect.cleanContext();
		}
	}

	//@Override
	//@WebResult(name = "CreatePDFSignatureResponseType", targetNamespace = "http://reference.e-government.gv.at/namespace/moa/20151109#")
	public CreatePDFSignatureResponseType createPDFSignature(CreatePDFSignatureRequest createPDFSignatureRequest)
			throws Exception {
		logger.info("createPDFSignature start");
		try {
			logger.info("WebServiceContext: {}", context);
			ContextSetupAspect.setupContext(context.getMessageContext(), "createPDFSignature");

			CreatePDFRequest requestObj;
			CreatePDFRespone responseObj;

			TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();

			// convert to API objects
			logger.trace(">>> preparsing Request");
			requestObj = this.pdfCreateSignatureBinding.buildPDFRequest(createPDFSignatureRequest);
			logger.trace("<<< preparsed Request");

			logger.trace(">>> creating Signature");
			// invoke the core logic
			responseObj = null;//PDFASInvoker.getInstance().createPDFSignature(requestObj, context.getTransactionID());
			logger.trace("<<< created Signature");

			logger.trace(">>> building Response");
			// map back to XML
			CreatePDFSignatureResponseType response = this.pdfCreateSignatureBinding.buildPDFResponse(responseObj);
			logger.trace("<<< built Response");

			return response;
		} catch (Throwable t) {
			MOASystemException e = new MOASystemException("2900", null, t);
			logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:"
					+ System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
			logger.error("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:", e);
			throw new Exception(e.getMessage());
		} finally {
			ContextSetupAspect.cleanContext();
		}
	}

}