import java.io.EOFException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.StreamCorruptedException;
import java.net.URL;
import java.net.URLConnection;

class Monitoring {

    private enum ServletName{LP, SDGW};
    private static final boolean TRACE_OUTPUT_PAYLOAD = true;
    private String servletHost;

    public Monitoring(String servletHost) {
        this.servletHost = servletHost;
    }

    /*
    some housekeeping handling
    */
    private void logger(String msg){
        System.out.println("######" + msg);
    }
    public boolean monitor() {
        Object result1 = null;
        try {
            result1 = (String) objectArrayToServlet("getDescByCode", new Object[]{"001", "AP008", "USD",(String) null}, ServletName.SDGW);
        } catch (Throwable e1) {
            e1.printStackTrace();
        }
        Object result2 = null;
        try {
            result2 = (Integer) objectArrayToServlet("getFieldLength", new Object[]{"H-WINSET-ID"}, ServletName.LP);
        } catch (Throwable e1) {
            e1.printStackTrace();
        }
        return result1 != null && result2 != null;
    }
    private Object objectArrayToServlet(String methodName, Object[] objectArray, ServletName servletType) throws Throwable
    {
        URLConnection servletConnection = null;
        switch(servletType) {
            case SDGW:
            {
                URL sdgwURL = new URL(servletHost + "ImexHTTPServlet?SDGW");
                servletConnection = sdgwURL.openConnection();
                break;
            }
            case LP:
            {
                URL lpURL = new URL(servletHost + "ImexHTTPServlet?LP");
                servletConnection = lpURL.openConnection();
                break;
            }
        }
        return objectArrayToServletImpl(servletConnection, methodName, objectArray, servletType);
    }

    /*
     here start the actual HTTP handling
    */
    private Object objectArrayToServletImpl(URLConnection servletConnection, String methodName, Object[] objectArray, ServletName servletType) throws Throwable
    {
        logger("Connection URL " + servletConnection.getURL());
        ObjectOutputStream outputToServlet = null;

// properties setting needed to be able to send binary
        servletConnection.setDoInput(true);
        servletConnection.setDoOutput(true);
        servletConnection.setUseCaches(false);
        servletConnection.setRequestProperty("Content-Type", "application/octet-stream");

// creating the outputstream to be able to send out parameters
        OutputStream out = servletConnection.getOutputStream();
// use decorator Stream in order to log the actual output
        if (TRACE_OUTPUT_PAYLOAD) out = new TraceOutputStream(out);
        outputToServlet = new ObjectOutputStream(out);

        outputToServlet.writeObject(methodName);
        outputToServlet.writeObject(objectArray);

        if(servletType == ServletName.SDGW) {
            outputToServlet.writeObject("NetTest");
            outputToServlet.writeObject(Integer.valueOf(3));
        }

        outputToServlet.flush();
//closing the stream
        outputToServlet.close();

        if (TRACE_OUTPUT_PAYLOAD) logger("Request Payload content " + ((TraceOutputStream)out).getTrace());
        logger("Response Header Fields " + servletConnection.getHeaderFields());

// calling the serletToObject method that get from the servlet an object and return it to this method
// returning the object to the method that called it
        return servletToObject(servletConnection,servletType);
    }

    private Object servletToObject(URLConnection servletConnection, ServletName servletType) throws Throwable
    {
        Object b = null;

//reading the object should nothing be returned we will fall on EOF
        try {
            InputStream is = servletConnection.getInputStream();
            String contentType = servletConnection.getContentType();
            logger("Respose ContentType " + contentType);
            ObjectInputStream inputFromServlet = new ObjectInputStream(is);
            logger("Respose going to read Object from stream...");
            b = inputFromServlet.readObject();
// closing the stream
            logger("Respose going to close InputStream...");
            inputFromServlet.close();
            logger("Respose InputStream closed.");
        }
        catch (StreamCorruptedException e){
            logger("Respose StreamCorruptedException " + e.getMessage());
            throw e;
        }
        catch (EOFException e){
            logger("Respose EOFException " + e.getMessage());
            throw e;
        }

//checking if an Exception was send from the servlet
        if (b instanceof Throwable){
            logger("servletToObject Throwable " + ((Throwable)b).getMessage());
            throw (Throwable)b;
        }

//returning the Object
        return b;
    }
} 