/*
 * 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.tuscany.sca.binding.jsonp.runtime;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class JSONPServlet extends GenericServlet {
    private static final long serialVersionUID = 1L;

    protected transient RuntimeEndpoint wire;
    protected transient Operation operation;
    protected transient ObjectMapper mapper;
    
    public JSONPServlet(RuntimeEndpoint wire, Operation operation) {
        this.wire = wire;
        this.operation = operation;
        this.mapper = new ObjectMapper();
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String jsonRequest = getJSONRequest(servletRequest);
        Object[] args = jsonToObjects(jsonRequest);
        Object response = invokeService(args);        
        String jsonResponse = getJSONResponse(servletRequest, response);
        servletResponse.getOutputStream().println(jsonResponse);
    }

    /**
     * Turn the request into JSON 
     */
    protected String getJSONRequest(ServletRequest servletRequest) throws IOException, JsonParseException, JsonMappingException {
        
        List<DataType> types = operation.getInputType().getLogical();
        int typesIndex = 0;
        
        String jsonRequest = "";
        for (String name : getOrderedParameterNames(servletRequest)) {
            if (!name.startsWith("_") && !"callback".equals(name)) {
                if (jsonRequest.length() > 1) {
                    jsonRequest += ", ";
                }

                // automatically quote string parammeters so clients work in the usual javascript way
                if (typesIndex < types.size() && String.class.equals(types.get(typesIndex).getGenericType())) {
                    String x = servletRequest.getParameter(name);
                    // TODO: do this more properly
                    if (!x.startsWith("\"")) {
                        jsonRequest += "\"" + x + "\"";
                    } else {
                        jsonRequest += x;
                    }
                } else {
                    jsonRequest += servletRequest.getParameter(name);
                }
                
            }
        }

        return "[" + jsonRequest + "]";
    }

    /**
     * Get the request parameter names in the correct order.
     * The request args need to be in the correct order to invoke the service so work out the
     * order from the order in the query string. Eg, the url:
     *   http://localhost:8085/HelloWorldService/sayHello2?first=petra&last=arnold&callback=foo"
     * should invoke:
     *   sayHello2("petra", "arnold")
     * so the parameter names should be ordered: "first", "last"
     */
    protected SortedSet<String> getOrderedParameterNames(ServletRequest servletRequest) {
        final String queryString = ((HttpServletRequest)servletRequest).getQueryString();

        SortedSet<String> sortedNames = new TreeSet<String>(new Comparator<String>(){
            public int compare(String o1, String o2) {
                int i = queryString.indexOf(o1);
                int j = queryString.indexOf(o2);
                return i - j;
            }});

        Set<String> parameterNames = servletRequest.getParameterMap().keySet();
        for (String name : parameterNames) {
            sortedNames.add(name);    
        }

        return sortedNames;
    }

    /**
     * Turn the response object into JSON 
     */
    protected String getJSONResponse(ServletRequest servletRequest, Object response) throws IOException, JsonParseException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        mapper.writeValue(os , response);
        String jsonResponse = os.toString();

        String callback = servletRequest.getParameter("callback");
        if (callback != null && callback.length() > 1) {
            jsonResponse = callback + "(" + jsonResponse + ");";
        }

        return jsonResponse;
    }

    /**
     * Turn the request JSON into objects 
     */
    protected Object[] jsonToObjects(String jsonRequest) throws IOException, JsonParseException, JsonMappingException {
        Class<?> c = new Object[0].getClass();
        Object[] args = (Object[])mapper.readValue(jsonRequest, c);
        return args;
    }

    /**
     * Send the request down the wire to invoke the service 
     */
    protected Object invokeService(Object[] args) {
        try {
            return wire.invoke(operation, args);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}