package at.gv.egovernment.moa.spss.server.service;

import java.util.Collections;

import javax.xml.namespace.QName;

import org.apache.axis.AxisFault;
import org.apache.axis.i18n.Messages;
import org.w3c.dom.Element;

import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.spss.MOAException;
import at.gv.egovernment.moa.spss.MOASystemException;
import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureRequestParser;
import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureResponseBuilder;
import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker;
import at.gv.egovernment.moa.util.Constants;
import at.gv.egovernment.moa.util.StreamUtils;

/**
 * The service endpoint for the <code>SignatureCreation</code> web service.
 * 
 * @author Patrick Peck
 * @version $Id$
 */
public class SignatureCreationService {

  /**
   * Handle a <code>CreateXMLSignatureRequest</code>.
   * 
   * @param request The <code>CreateXMLSignatureRequest</code> to work on
   * (contained in the 0th element of the array).
   * @return A <code>CreateXMLSignatureResponse</code> as the only element of
   * the <code>Element</code> array.
   * @throws AxisFault An error occurred during handling of the message.
   */
  public Element[] CreateXMLSignatureRequest(Element[] request)
    throws AxisFault {
    XMLSignatureCreationInvoker invoker =
      XMLSignatureCreationInvoker.getInstance();
    Element[] response = new Element[1];

    // check that we have a CreateXMLSignatureRequest; if not, create an
    // AxisFault, just like the org.apache.axis.providers.java.MsgProvider
    if (!Constants.MOA_SPSS_CREATE_XML_REQUEST.equals(request[0].getLocalName()) ||
      !Constants.MOA_NS_URI.equals(request[0].getNamespaceURI()))
    {
      QName qname =
        new QName(request[0].getNamespaceURI(), request[0].getLocalName());
      throw new AxisFault(
        Messages.getMessage("noOperationForQName", qname.toString())); // TODO GK Operation name does not make it into the error repsonse
    }

    // handle the request
    try {
      // create a parser and builder for binding API objects to/from XML
      CreateXMLSignatureRequestParser requestParser =
        new CreateXMLSignatureRequestParser();
      CreateXMLSignatureResponseBuilder responseBuilder =
        new CreateXMLSignatureResponseBuilder();
      Element reparsedReq;
      CreateXMLSignatureRequest requestObj;
      CreateXMLSignatureResponse responseObj;

      // validate the request
      reparsedReq = ServiceUtils.reparseRequest(request[0]);

      // convert to API objects
      requestObj = requestParser.parse(reparsedReq);

      // invoke the core logic
      responseObj =
        invoker.createXMLSignature(requestObj, Collections.EMPTY_SET);

      // map back to XML
      response[0] = responseBuilder.build(responseObj).getDocumentElement();

    } catch (MOAException e) {
      AxisFault fault = AxisFault.makeFault(e);
      fault.setFaultDetail(new Element[] { e.toErrorResponse()});
      Logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:" 
        + System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
      throw fault;
    } catch (Throwable t) {
      MOASystemException e = new MOASystemException("2900", null, t);
      AxisFault fault = AxisFault.makeFault(e);
      fault.setFaultDetail(new Element[] { e.toErrorResponse()});
      Logger.debug("Anfrage zur Signaturerstellung wurde nicht erfolgreich beendet:" 
        + System.getProperty("line.separator") + StreamUtils.getStackTraceAsString(e));
      throw fault;
    }

    return response;
  }
}