/**
 * 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.servicemix.cxf.transport.nmr;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.activation.DataHandler;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;

import org.apache.cxf.attachment.AttachmentImpl;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.message.Attachment;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.AbstractConduit;
import org.apache.cxf.transport.AbstractDestination;
import org.apache.cxf.transport.Conduit;
import org.apache.cxf.transport.MessageObserver;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.apache.cxf.wsdl.EndpointReferenceUtils;
import org.apache.servicemix.nmr.api.Channel;
import org.apache.servicemix.nmr.api.Endpoint;
import org.apache.servicemix.nmr.api.Exchange;
import org.apache.servicemix.nmr.api.NMR;
import org.apache.servicemix.nmr.api.Pattern;
import org.apache.servicemix.nmr.api.ServiceMixException;
import org.apache.servicemix.nmr.api.Status;

public class NMRDestination extends AbstractDestination implements Endpoint {
    
    private static final Logger LOG = LogUtils.getL7dLogger(NMRDestination.class);
    private NMR nmr;
    private Channel channel;
    private Map<String, Object> properties;

    public NMRDestination(EndpointInfo info, NMR nmr) {
        super(getTargetReference(info, null), info);
        this.nmr = nmr;
        this.properties = new HashMap<String, Object>();
        String address = info.getAddress();
        if (address != null && address.indexOf(Endpoint.RUN_AS_SUBJECT) >= 0) {
        	String asSubject = address.substring(address.indexOf(Endpoint.RUN_AS_SUBJECT) 
        			+ Endpoint.RUN_AS_SUBJECT.length() + 1);
        	this.properties.put(Endpoint.RUN_AS_SUBJECT, asSubject);
        }
        if (address != null && address.startsWith("nmr:")) {
        	if (address.indexOf("?") > 0) {
        		this.properties.put(Endpoint.NAME, address.substring(4, address.indexOf("?")));
        	} else {
        		this.properties.put(Endpoint.NAME, address.substring(4));
        	}
        } else {
            this.properties.put(Endpoint.NAME, info.getName().toString());
        }
        
        this.properties.put(Endpoint.SERVICE_NAME, info.getService().getName().toString());
        this.properties.put(Endpoint.INTERFACE_NAME, info.getInterface().getName().toString());
        
        if (address.indexOf("?") > 0) {
            String[] props = address.substring(address.indexOf("?") + 1).split("&");
            for (String prop : props) {
                if (prop.indexOf("=") > 0) {
                    String key = prop.substring(0, prop.indexOf("="));
                    String val = prop.substring(prop.indexOf("=") + 1);
                    if (key.equals("synchronous")) {
                        key = Endpoint.CHANNEL_SYNC_DELIVERY;
                    }
                    this.properties.put(key, val);
                }
            }
        }
    }

    public void setChannel(Channel dc) {
        this.channel = dc;
    }
    
    public Channel getChannel() {
        return this.channel;
    }
    
    protected Logger getLogger() {
        return LOG;
    }
    
    /**
     * @param inMessage the incoming message
     * @return the inbuilt backchannel
     */
    protected Conduit getInbuiltBackChannel(Message inMessage) {
        return new BackChannelConduit(EndpointReferenceUtils.getAnonymousEndpointReference(),
                                      inMessage);
    }
    
    public void shutdown() {
    }

    public void deactivate() {
        nmr.getEndpointRegistry().unregister(this, properties);
    }

    public void activate()  {
        nmr.getEndpointRegistry().register(this, properties);
    }

    public void process(Exchange exchange) {
        if (exchange == null || exchange.getStatus() != Status.Active) {
            return;
        }
        if (exchange.getPattern() == Pattern.InOnly || exchange.getPattern() == Pattern.RobustInOnly) {
            exchange.setStatus(Status.Done);
            getChannel().send(exchange);
        }
        QName opName = exchange.getOperation();
        getLogger().fine("dispatch method: " + opName);

        org.apache.servicemix.nmr.api.Message nm = exchange.getIn();
        try {

            MessageImpl inMessage = new MessageImpl();
            inMessage.put(Exchange.class, exchange);
            
            final InputStream in = NMRMessageHelper.convertMessageToInputStream(nm.getBody(Source.class));
            inMessage.setContent(InputStream.class, in);
            //copy attachments
            Collection<Attachment> cxfAttachmentList = new ArrayList<Attachment>();
            for (Map.Entry<String, Object> ent : nm.getAttachments().entrySet()) {
                cxfAttachmentList.add(new AttachmentImpl(ent.getKey(), (DataHandler) ent.getValue()));
            }
            inMessage.setAttachments(cxfAttachmentList);
            
            //copy properties and setup the cxf protocol header
            Map<String, List<String>> protocolHeaders = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
            inMessage.put(Message.PROTOCOL_HEADERS, protocolHeaders);

            for (Map.Entry<String, Object> ent : nm.getHeaders().entrySet()) {
                if (!ent.getKey().equals(Message.REQUESTOR_ROLE)) {
                    inMessage.put(ent.getKey(), ent.getValue());
                }
                if (ent.getValue() instanceof String) {
            	    List<String> value = new ArrayList<String>();
            	    value.add((String)ent.getValue());
            	    protocolHeaders.put(ent.getKey(), value);
                }
            }
            
            //copy securitySubject
            inMessage.put(NMRTransportFactory.NMR_SECURITY_SUBJECT, nm.getSecuritySubject());
            
            inMessage.setDestination(this);
            getMessageObserver().onMessage(inMessage);

        } catch (Exception ex) {
            getLogger().log(Level.SEVERE, new org.apache.cxf.common.i18n.Message("ERROR.PREPARE.MESSAGE", getLogger()).toString(), ex);
            throw new ServiceMixException(ex);
        }
    }


    protected class BackChannelConduit extends AbstractConduit {
        
        protected Message inMessage;
        protected NMRDestination nmrDestination;
                
        BackChannelConduit(EndpointReferenceType ref, Message message) {
            super(ref);
            inMessage = message;
        }
        
        /**
         * Register a message observer for incoming messages.
         * 
         * @param observer the observer to notify on receipt of incoming
         */
        public void setMessageObserver(MessageObserver observer) {
            // shouldn't be called for a back channel conduit
        }

        /**
         * Send an outbound message, assumed to contain all the name-value
         * mappings of the corresponding input message (if any). 
         * 
         * @param message the message to be sent.
         */
        public void prepare(Message message) throws IOException {
            // setup the message to be send back
            Channel dc = channel;
            message.put(Exchange.class, inMessage.get(Exchange.class));
            NMRTransportFactory.removeUnusedInterceptprs(message);    
            message.setContent(OutputStream.class, new NMRDestinationOutputStream(inMessage, message, dc));
            
        }        

        protected Logger getLogger() {
            return LOG;
        }
        
    }
    
}
