/*
 * 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.ArrayList;
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[] args = getJSONRequestStringArray(servletRequest);
        Object response = invokeService(args);        
        //String jsonResponse = getJSONResponse(servletRequest, response);
        String jsonResponse = getJSONResponseAsString(servletRequest, response);
        servletResponse.getOutputStream().println(jsonResponse);
    }

    /**
     * Turn the request into JSON 
     */
/* Not required now JSON conversion is delegated to databinding       
    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 + "]";
    }
*/
    
    /**
     * Turn the request into a string array of JSON structures. The Databinding
     * layer will then convert each of the individual parameters into the appropriate
     * types for the implementation interface
     * 
     */
    protected Object[] getJSONRequestStringArray(ServletRequest servletRequest) throws IOException, JsonParseException, JsonMappingException {
        
        List<DataType> types = operation.getInputType().getLogical();
        int typesIndex = 0;
        
        List<String> jsonRequestArray = new ArrayList<String>();
        
        for (String name : getOrderedParameterNames(servletRequest)) {
            String jsonRequest = "";
            if (!name.startsWith("_") && !"callback".equals(name)) {

                // automatically quote string parameters 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);
                }  
                jsonRequestArray.add(jsonRequest);
            }
        }

        return jsonRequestArray.toArray();
    }    

    /**
     * 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 
     */
/* Not required now JSON conversion is delegated to databinding   
    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;
    }
*/
    
    /**
     * The databinding layer will have converterted the return type into a JSON string so simply 
     * add wrap it for return.
     */
    protected String getJSONResponseAsString(ServletRequest servletRequest, Object response) throws IOException, JsonParseException {
        String jsonResponse = response.toString();

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

        return jsonResponse;
    }    

    /**
     * Turn the request JSON into objects 
     */
/* Not required now JSON conversion is delegated to databinding       
    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);
        }
    }
}