/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.xml.internal.ws.db;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.xml.ws.WebServiceFeature;

import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
import com.oracle.webservices.internal.api.message.MessageContext;
import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.internal.ws.api.databinding.Databinding;
import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
import com.sun.xml.internal.ws.api.message.Message;
import com.sun.xml.internal.ws.api.message.MessageContextFactory;
import com.sun.xml.internal.ws.api.message.Packet;
import com.sun.xml.internal.ws.api.model.MEP;
import com.sun.xml.internal.ws.api.model.SEIModel;
import com.sun.xml.internal.ws.api.model.WSDLOperationMapping;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.internal.ws.api.pipe.Codec;
import com.sun.xml.internal.ws.api.pipe.ContentType;
import com.sun.xml.internal.ws.binding.BindingImpl;
import com.sun.xml.internal.ws.client.sei.StubAsyncHandler;
import com.sun.xml.internal.ws.client.sei.StubHandler;
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
import com.sun.xml.internal.ws.model.JavaMethodImpl;
import com.sun.xml.internal.ws.model.RuntimeModeler;
import com.sun.xml.internal.ws.server.sei.TieHandler;
import com.sun.xml.internal.ws.wsdl.ActionBasedOperationSignature;
import com.sun.xml.internal.ws.wsdl.DispatchException;
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;

/**
 * WsRuntimeImpl is the databinding processor built on SEIModel
 *
 * @author shih-chang.chen@oracle.com
 */
public class DatabindingImpl implements Databinding {

    AbstractSEIModelImpl seiModel;
        Map<Method, StubHandler> stubHandlers;
//    QNameMap<TieHandler> wsdlOpMap = new QNameMap<TieHandler>();
        Map<JavaMethodImpl, TieHandler> wsdlOpMap = new HashMap<JavaMethodImpl, TieHandler>();
        Map<Method, TieHandler> tieHandlers = new HashMap<Method, TieHandler>();
    OperationDispatcher operationDispatcher;
    OperationDispatcher operationDispatcherNoWsdl;
    boolean clientConfig = false;
    Codec codec;
    MessageContextFactory packetFactory = null;

        public DatabindingImpl(DatabindingProviderImpl p, DatabindingConfig config) {
                RuntimeModeler modeler = new RuntimeModeler(config);
                modeler.setClassLoader(config.getClassLoader());
                seiModel = modeler.buildRuntimeModel();
                WSDLPort wsdlport = config.getWsdlPort();
                packetFactory = new MessageContextFactory(seiModel.getWSBinding().getFeatures());
                clientConfig = isClientConfig(config);
                if ( clientConfig ) initStubHandlers();
                seiModel.setDatabinding(this);
                if (wsdlport != null) freeze(wsdlport);
                if (operationDispatcher == null) operationDispatcherNoWsdl = new OperationDispatcher(null, seiModel.getWSBinding(), seiModel);
//    if(!clientConfig) {
                for(JavaMethodImpl jm: seiModel.getJavaMethods()) if (!jm.isAsync()) {
            TieHandler th = new TieHandler(jm, seiModel.getWSBinding(), packetFactory);
            wsdlOpMap.put(jm, th);
            tieHandlers.put(th.getMethod(), th);
        }
//    }
        }

        //TODO isClientConfig
        private boolean isClientConfig(DatabindingConfig config) {
                if (config.getContractClass() == null) return false;
                if (!config.getContractClass().isInterface()) return false;
                return (config.getEndpointClass() == null || config.getEndpointClass().isInterface());
        }
        //TODO fix freeze
        public synchronized void freeze(WSDLPort port) {
                if (clientConfig) return;
                if (operationDispatcher != null) return;
                operationDispatcher = (port == null) ? null : new OperationDispatcher(port, seiModel.getWSBinding(), seiModel);
        }

        public SEIModel getModel() {
                return seiModel;
        }
//Refactored from SEIStub
    private void initStubHandlers() {
                stubHandlers = new HashMap<Method, StubHandler>();
        Map<ActionBasedOperationSignature, JavaMethodImpl> syncs = new HashMap<ActionBasedOperationSignature, JavaMethodImpl>();
        // fill in methodHandlers.
        // first fill in sychronized versions
        for (JavaMethodImpl m : seiModel.getJavaMethods()) {
            if (!m.getMEP().isAsync) {
                StubHandler handler = new StubHandler(m, packetFactory);
                syncs.put(m.getOperationSignature(), m);
                stubHandlers.put(m.getMethod(), handler);
            }
        }
        for (JavaMethodImpl jm : seiModel.getJavaMethods()) {
            JavaMethodImpl sync = syncs.get(jm.getOperationSignature());
            if (jm.getMEP() == MEP.ASYNC_CALLBACK || jm.getMEP() == MEP.ASYNC_POLL) {
                Method m = jm.getMethod();
                StubAsyncHandler handler = new StubAsyncHandler(jm, sync, packetFactory);
                stubHandlers.put(m, handler);
            }
        }
    }

    public JavaMethodImpl resolveJavaMethod(Packet req) throws DispatchException {
        WSDLOperationMapping m = req.getWSDLOperationMapping();
        if (m == null) m = (operationDispatcher != null) ?
                operationDispatcher.getWSDLOperationMapping(req):
                operationDispatcherNoWsdl.getWSDLOperationMapping(req);
        return (JavaMethodImpl) m.getJavaMethod();
    }

        public JavaCallInfo deserializeRequest(Packet req) {
            com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo();
                try {
                    JavaMethodImpl wsdlOp = resolveJavaMethod(req);
                        TieHandler tie = wsdlOpMap.get(wsdlOp);
                        call.setMethod(tie.getMethod());
                        Object[] args = tie.readRequest(req.getMessage());
                        call.setParameters(args);
                } catch (DispatchException e) {
                        call.setException(e);
                }
                return call;
        }

        public JavaCallInfo deserializeResponse(Packet res, JavaCallInfo call) {
        StubHandler stubHandler = stubHandlers.get(call.getMethod());
        try {
            return stubHandler.readResponse(res, call);
        } catch (Throwable e) {
            call.setException(e);
            return call;
        }
        }

        public WebServiceFeature[] getFeatures() {
                // TODO Auto-generated method stub
                return null;
        }

        public Packet serializeRequest(JavaCallInfo call) {
        StubHandler stubHandler = stubHandlers.get(call.getMethod());
        Packet p = stubHandler.createRequestPacket(call);
        p.setState(Packet.State.ClientRequest);
        return p;
        }

        public Packet serializeResponse(JavaCallInfo call) {
                Method method = call.getMethod();
                Message message = null;
                if (method != null) {
                        TieHandler th = tieHandlers.get(method);
                        if (th != null) {
                            return th.serializeResponse(call);
                        }
                }
                if (call.getException() instanceof DispatchException) {
                    message = ((DispatchException)call.getException()).fault;
                }
        Packet p = (Packet)packetFactory.createContext(message);
        p.setState(Packet.State.ServerResponse);
        return p;
        }

        public ClientCallBridge getClientBridge(Method method) {
                return stubHandlers.get(method);
        }


        public void generateWSDL(WSDLGenInfo info) {
            com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator wsdlGen = new com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator(
                    seiModel,
                    info.getWsdlResolver(),
                    seiModel.getWSBinding(),
                    info.getContainer(), seiModel.getEndpointClass(),
                    info.isInlineSchemas(),
            info.isSecureXmlProcessingDisabled(),
            info.getExtensions());
        wsdlGen.doGeneration();
        }

        public EndpointCallBridge getEndpointBridge(Packet req) throws DispatchException {
        JavaMethodImpl wsdlOp = resolveJavaMethod(req);
                return wsdlOpMap.get(wsdlOp);
        }


        Codec getCodec() {
                if (codec == null) codec = ((BindingImpl)seiModel.getWSBinding()).createCodec();
                return codec;
        }

        public ContentType encode( Packet packet, OutputStream out ) throws IOException {
        return getCodec().encode(packet, out);
    }

        public void decode( InputStream in, String ct, Packet p ) throws IOException{
        getCodec().decode(in, ct, p);
    }

    public com.oracle.webservices.internal.api.databinding.JavaCallInfo createJavaCallInfo(Method method, Object[] args) {
        return new com.sun.xml.internal.ws.api.databinding.JavaCallInfo(method, args);
    }

    public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeResponse(
            MessageContext message, com.oracle.webservices.internal.api.databinding.JavaCallInfo call) {
        return deserializeResponse((Packet)message, (JavaCallInfo)call);
    }

    public com.oracle.webservices.internal.api.databinding.JavaCallInfo deserializeRequest(MessageContext message) {
        return deserializeRequest((Packet)message);
    }

    public MessageContextFactory getMessageContextFactory() {
        return packetFactory;
    }
}
