package com.korsengineering.ws.microwss.test;

import com.korsengineering.ws.microwss.ComplexType;
import com.korsengineering.ws.microwss.Operation;
import com.korsengineering.ws.microwss.Optional;
import com.korsengineering.ws.microwss.Server;

import java.io.IOException;
import java.io.InputStream;
import javax.servlet.*;
import javax.servlet.http.*;

/** This class shows how to build a web service using MicroWSS toolkit. */
public class DemoService  extends HttpServlet {
    /* First, we need to create request and response structures.
     * We do that by extending ComplexType in both cases. */
    
    public static class WeatherRequest extends ComplexType{
        int zip;
    }

    public static class WeatherResponse extends ComplexType{
        WeatherInfo[] forecasts; //we can next ComplexTypes and arrays of complex types.
    }

    public static class WeatherInfo extends ComplexType{
        int forZip;
        String date;
        int temp;
        @Optional String wind; // the annoation sets minOccurs="0"
    }

    //Operation object will be created every time the operation is performed
    public static class WeatherForecast extends Operation{
        protected WeatherRequest request = new WeatherRequest();
        protected WeatherResponse response = new WeatherResponse();

        public ComplexType getRequest(){
            return request; //It's important to return object attributes, rather than some other variables
        }

        public ComplexType getResponse(){
            return response;
        }

        /* This method translates request into response. When someone
         sends XML for an operation, the server will instantiate this object,
         populate the request object, then call translate method. When it's done,
         the server will use contents of response object to construct SOAP response. */
        public void translate(){
            response.forecasts = new WeatherInfo[2];
            response.forecasts[0] = new WeatherInfo();
            response.forecasts[1] = new WeatherInfo();

            response.forecasts[0].forZip = request.zip;
            response.forecasts[0].date = "2009-01-01";
            response.forecasts[0].temp = 20;
            response.forecasts[0].wind = "North-West";

            response.forecasts[1].forZip = request.zip;
            response.forecasts[1].date = "2009-01-02";
            response.forecasts[1].temp = 15;
        }
    }

    protected Server wsServer = new Server();

    @Override
    public void init() throws ServletException {
        super.init();
        // Setting a reasonabme namespace is a good idea (though not mandatory)
        wsServer.setTargetNs("http://example.com/tagetNamespace");
        // Need to register all operations before they can be seen/used
        wsServer.register(WeatherForecast.class);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        String location = request.getRequestURL().toString();
        response.setContentType("text/xml");
        try {
            response.getWriter().write(wsServer.getWsdl(location));
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            String requestStr = slurp(request.getInputStream());
            String responseStr = wsServer.serve(requestStr);
            response.setContentType("application/soap+xml; charset=utf-8");
            response.getWriter().write(responseStr);
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String slurp(InputStream in) throws IOException {
        StringBuilder out = new StringBuilder();
        byte[] bytes = new byte[4096];
        for (int n; (n = in.read(bytes)) != -1;) {
            out.append(new String(bytes, 0, n));
        }
        return out.toString();
    }

    @Override
    public String getServletInfo() {
        return "MicroWSS Demo";
    }
}