/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ode.axis2.hooks;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.description.*;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.transport.jms.JMSConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.axis2.OdeFault;
import org.apache.ode.axis2.util.Axis2UriResolver;
import org.apache.ode.axis2.util.Axis2WSDLLocator;
import org.apache.ode.axis2.util.AxisUtils;
import org.apache.ode.bpel.iapi.ProcessConf;
import org.apache.ode.bpel.epr.WSDL11Endpoint;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.GUID;
import org.apache.ode.utils.Properties;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.w3c.dom.Element;

/**
 * Implementation of Axis Service used by ODE iapi to enlist itself its service. Allows us to build the service using a
 * WSDL definition using our own receiver.
 */
public class ODEAxisService {

    private static final Logger LOG = LoggerFactory.getLogger(ODEAxisService.class);

    public static AxisService createService(AxisConfiguration axisConfig, ProcessConf pconf, QName wsdlServiceName, String portName) throws AxisFault {
        Definition wsdlDefinition = pconf.getDefinitionForService(wsdlServiceName);

        if (LOG.isDebugEnabled()) {
            LOG.debug("Create AxisService:"+" service="+wsdlServiceName+" port="+portName
                    +" WSDL="+wsdlDefinition.getDocumentBaseURI()+" BPEL="+pconf.getBpelDocument());
        }

        InputStream is = null;
        try {
            URI baseUri = pconf.getBaseURI().resolve(wsdlDefinition.getDocumentBaseURI());
            is = baseUri.toURL().openStream();
            WSDL11ToAxisPatchedBuilder serviceBuilder = new WSDL11ToAxisPatchedBuilder(is, wsdlServiceName, portName);
            serviceBuilder.setBaseUri(baseUri.toString());
            serviceBuilder.setCustomResolver(new Axis2UriResolver());
            serviceBuilder.setCustomWSLD4JResolver(new Axis2WSDLLocator(baseUri));
            serviceBuilder.setServerSide(true);

            String axisServiceName = ODEAxisService.extractServiceName(pconf, wsdlServiceName, portName);

            AxisService axisService = serviceBuilder.populateService();
            axisService.setParent(axisConfig);
            axisService.setName(axisServiceName);
            axisService.setWsdlFound(true);
            axisService.setCustomWsdl(true);
            axisService.setClassLoader(axisConfig.getServiceClassLoader());

            URL wsdlUrl = null;
            for (File file : pconf.getFiles()) {
                if (file.getAbsolutePath().indexOf(wsdlDefinition.getDocumentBaseURI()) > 0)
                    wsdlUrl = file.toURI().toURL();
            }
            if (wsdlUrl != null) axisService.setFileName(wsdlUrl);

            // axis2 service configuration
            URL service_file = pconf.getBaseURI().resolve(wsdlServiceName.getLocalPart()+".axis2").toURL();
            if (LOG.isDebugEnabled()) {
                LOG.debug("Looking for Axis2 service configuration file: "+service_file);
            }
            try {
                AxisUtils.configureService(axisService, service_file);
            } catch (FileNotFoundException except) {
                LOG.debug("Axis2 service configuration not found: " + service_file);
            } catch (IOException except) {
                LOG.warn("Exception while configuring service: " + service_file, except);
            }


            final WSDL11Endpoint endpoint = new WSDL11Endpoint(wsdlServiceName, portName);
            final Map<String, String> properties = pconf.getEndpointProperties(endpoint);
            if(properties.get(Properties.PROP_SECURITY_POLICY)!=null){
                AxisUtils.applySecurityPolicy(axisService, properties.get(Properties.PROP_SECURITY_POLICY));
            }

            // In doc/lit we need to declare a mapping between operations and message element names
            // to be able to route properly.
            declarePartsElements(wsdlDefinition, wsdlServiceName, axisServiceName, portName);

            Iterator operations = axisService.getOperations();
            ODEMessageReceiver msgReceiver = new ODEMessageReceiver();
            while (operations.hasNext()) {
                AxisOperation operation = (AxisOperation) operations.next();
                if (operation.getMessageReceiver() == null) {
                    operation.setMessageReceiver(msgReceiver);
                }
            }

            // Set the JMS destination name on the Axis Service
            if (isJmsEndpoint(pconf, wsdlServiceName, portName)) {
                axisService.addParameter(new Parameter(JMSConstants.PARAM_DESTINATION,
                        extractJMSDestinationName(axisServiceName, deriveBaseServiceUri(pconf))));
            }

            return axisService;
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        } finally {
            try {
                if( is!=null) is.close();
            } catch (IOException ioe) {
                //Ignoring
            }
        }
    }

    /**
     * Extract the JMS destination name that is embedded in the Axis service name.
     * @param axisServiceName the name of the axis service
     * @return the corresponding JMS destination name
     */
    private static String extractJMSDestinationName(String axisServiceName, String baseUri) {
        String destinationPrefix = "dynamicQueues/";
        int index = axisServiceName.indexOf(destinationPrefix);
        if (index == -1) {
            destinationPrefix = "dynamicTopics/";
            index = axisServiceName.indexOf(destinationPrefix);
        }
        if (index == -1) {
            destinationPrefix = baseUri + "/";
            index = axisServiceName.indexOf(destinationPrefix);
            return (index != -1) ? axisServiceName.substring(destinationPrefix.length()) : axisServiceName;
        } else {
            return axisServiceName.substring(index);
        }
    }

    public static AxisService createService(AxisConfiguration axisConfig, QName serviceQName, String port,
                                            String axisName, Definition wsdlDef, MessageReceiver receiver) throws AxisFault {

        WSDL11ToAxisServiceBuilder serviceBuilder = new WSDL11ToAxisServiceBuilder(wsdlDef, serviceQName, port);
        AxisService axisService = serviceBuilder.populateService();
        axisService.setName(axisName);
        axisService.setWsdlFound(true);
        axisService.setClassLoader(axisConfig.getServiceClassLoader());
        Iterator operations = axisService.getOperations();
        while (operations.hasNext()) {
            AxisOperation operation = (AxisOperation) operations.next();
            if (operation.getMessageReceiver() == null) {
                operation.setMessageReceiver(receiver);
            }
        }
        return axisService;
    }

    private static String extractEndpointUri(ProcessConf pconf, QName wsdlServiceName, String portName)
            throws AxisFault {
        Definition wsdlDefinition = pconf.getDefinitionForService(wsdlServiceName);
        String url = null;
        Service service = wsdlDefinition.getService(wsdlServiceName);
        if (service == null) {
            throw new OdeFault("Unable to find service " + wsdlServiceName + " from service WSDL definition "
                    + wsdlDefinition.getDocumentBaseURI());
        }
        Port port = service.getPort(portName);
        if (port == null) {
            throw new OdeFault("Couldn't find port " + portName + " in definition " + wsdlServiceName);
        }
        for (Object oext : port.getExtensibilityElements()) {
            if (oext instanceof SOAPAddress)
                url = ((SOAPAddress) oext).getLocationURI();
        }
        if (url == null) {
            throw new OdeFault("Could not extract any soap:address from service WSDL definition " + wsdlServiceName
                    + " (necessary to establish the process target address)!");
        }
        return url;
    }

    private static boolean isJmsEndpoint(ProcessConf pconf, QName wsdlServiceName, String portName)
            throws AxisFault {
        String url = extractEndpointUri(pconf, wsdlServiceName, portName);
        return url.startsWith("jms:");
    }

    private static String extractServiceName(ProcessConf pconf, QName wsdlServiceName, String portName)
            throws AxisFault {
        String endpointUri = extractEndpointUri(pconf, wsdlServiceName, portName);
        String derivedUri = deriveBaseServiceUri(pconf);
        String serviceName = parseURLForService(endpointUri, derivedUri);
        if (serviceName == null) {
            throw new OdeFault("The soap:address "+endpointUri+" used for service " + wsdlServiceName + " and port "
                    + portName + " should be of the form http://hostname:port/ode/processes/myProcessEndpointName");
        }
        return serviceName;
    }

    /**
     * Obtain the service name from the request URL. The request URL is expected to use the path "/processes/" under
     * which all processes and their services are listed. Returns null if the path does not contain this part.
     */
    protected static String parseURLForService(String path, String baseUri) {
        // Assume that path is HTTP-based, by default
        String servicePrefix = "/processes/";
        // Don't assume JMS-based paths start the same way
        if (path.startsWith("jms:/")) {
            servicePrefix = "jms:/";
        }
        int index = path.indexOf(servicePrefix);
        if (-1 != index) {
            String service;

            int serviceStart = index + servicePrefix.length();
            if (path.length() > serviceStart) {
                service = path.substring(serviceStart);
                // Path may contain query string, not interesting for us.
                int queryIndex = service.indexOf('?');
                if (queryIndex > 0) {
                    service = service.substring(0, queryIndex);
                }
                // Qualify shared JMS names with unique baseUri
                // Since multiple processes may provide services at the same (JMS) endpoint, qualify
                // the (JMS) endpoint-specific NCName with a process-relative URI, if necessary.
                if (path.startsWith("jms:/")) {
                    boolean slashPresent = baseUri.endsWith("/") || service.startsWith("/");
                    // service = baseUri + (slashPresent ? "" : "/") + service; // allow successive slashes ("//") in the URI
                    service = baseUri + "/" + service;
                }
                return service;
            }
        }
        return null;
    }

    private static void declarePartsElements(Definition wsdlDefinition, QName wsdlServiceName, String axisServiceName,
                                             String portName) {
        List wsldOps = wsdlDefinition.getService(wsdlServiceName).getPort(portName).getBinding().getPortType()
                .getOperations();
        for (Object wsldOp : wsldOps) {
            Operation wsdlOp = (Operation) wsldOp;
            Collection parts = wsdlOp.getInput().getMessage().getParts().values();
            // More than one part, it's rpc/enc, no mapping needs to be declared
            if (parts.size() == 1) {
                Part part = (Part) parts.iterator().next();
                // Parts are types, it's rpc/enc, no mapping needs to be declared
                if (part.getElementName() != null)
                    ODEAxisOperationDispatcher.addElmtToOpMapping(axisServiceName, wsdlOp.getName(), part.getElementName()
                            .getLocalPart());
            }
        }
    }

    // Axis2 monkey patching to force the usage of the read(element,baseUri) method
    // of XmlSchema as the normal read is broken.
    public static class WSDL11ToAxisPatchedBuilder extends WSDL11ToAxisServiceBuilder {
        public WSDL11ToAxisPatchedBuilder(InputStream in, QName serviceName, String portName) {
            super(in, serviceName, portName);
        }
        public WSDL11ToAxisPatchedBuilder(Definition def, QName serviceName, String portName) {
            super(def, serviceName, portName);
        }
        public WSDL11ToAxisPatchedBuilder(Definition def, QName serviceName, String portName, boolean isAllPorts) {
            super(def, serviceName, portName, isAllPorts);
        }
        public WSDL11ToAxisPatchedBuilder(InputStream in, AxisService service) {
            super(in, service);
        }
        public WSDL11ToAxisPatchedBuilder(InputStream in) {
            super(in);
        }

        private static Map<String, WeakReference<XmlSchema>> cached = new HashMap<String, WeakReference<XmlSchema>>();
        
        protected XmlSchema getXMLSchema(Element element, String baseUri) {
            synchronized (cached) {
//              String digest = GUID.makeGUID("" + baseUri + ";" + DOMUtils.domToString(element));
                String digest = baseUri;
                if (LOG.isDebugEnabled()) {
                    LOG.debug("getXMLSchema identity: " + System.identityHashCode(element) + " baseURI: " + baseUri + " elementBaseURI: " + element.getBaseURI() + " documentBaseURI:" + element.getOwnerDocument().getBaseURI() + " documentURI: " + element.getOwnerDocument().getDocumentURI() + " digest: " + digest);
                }
                if (cached.containsKey(digest)) {
                    XmlSchema s = cached.get(digest).get();
                    if (s != null) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Cache hit for schema guid " + digest);
                        }
                        return s;
                    }
                }
                
                XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
                if (baseUri != null) {
                    schemaCollection.setBaseUri(baseUri);
                }
                XmlSchema schema = schemaCollection.read(element, baseUri);
                cached.put(digest, new WeakReference<XmlSchema>(schema));
                return schema;
            }
        }
    }

    /*
     * Generates a URI of the following form:
     *     ${deploy_bundleNcName}/${diagram_relativeURL}/${process_relativeURL}
     * When a service name (local part only) is qualified (prefixed) with the above,
     * it results in a unique identifier that may be used as that service's name.
     */
    public static String deriveBaseServiceUri(ProcessConf pconf) {
        if (pconf != null) {
            StringBuffer baseServiceUri = new StringBuffer();
            String bundleName = pconf.getPackage();
            if (bundleName != null) {
                baseServiceUri.append(bundleName).append("/");
                if (pconf.getBpelDocument() != null) {
                    String bpelDocumentName = pconf.getBpelDocument();
                    if (bpelDocumentName.indexOf(".") > 0) {
                        bpelDocumentName = bpelDocumentName.substring(0, bpelDocumentName.indexOf("."));
                    }
                    baseServiceUri.append(bpelDocumentName).append("/");
                    String processName = pconf.getType() != null
                        ? pconf.getType().getLocalPart() : null;
                    if (processName != null) {
                        baseServiceUri.append(processName);
                        return baseServiceUri.toString();
                    }
                }
            }

        }
        return null;
    }

}
