/* MIT ICT4DLab SMS Lab framework
 * 
 * Copyright (C) 2008, Massachusetts Institute of Technology
 * 
 * ICT4DLab SMS is distributed under the terms of the Apache License version 2.0
 * 
 * Licensed 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.
 * 
 * original author: Luis F. G. Sarmenta ( lfgs @ mit . edu ) 
 * v0.1.0: 20080228
 * 
 * Last modified by:
 * date:
 * comment:
 */

package org.ict4dlab.sms.adapters.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ict4dlab.sms.core.SMSAppUtil;
import org.ict4dlab.sms.core.SMSApplication;
import org.ict4dlab.sms.core.SMSMessage;
import org.ict4dlab.sms.core.SMSSender;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.AbstractHandler;

public class SimpleGETAdapter implements SMSSender {

    private SMSApplication smsApp;

    // receiving info
    private int localServerPort = 14000;

    // sending info
    private String senderHostName = "192.168.62.68";
    private String destPortString = "13013";
    private String userName = "tester";
    private String password = "foobar";

    public SimpleGETAdapter(SMSApplication smsApp) {
	super();
	this.smsApp = smsApp;
	this.smsApp.setSMSSender(this);
    }

    public int getLocalServerPort() {
	return localServerPort;
    }

    public void setLocalServerPort(int localServerPort) {
	this.localServerPort = localServerPort;
    }

    public String getSenderHostName() {
	return senderHostName;
    }

    public void setSenderHostName(String senderHostName) {
	this.senderHostName = senderHostName;
    }

    public String getDestPortString() {
	return destPortString;
    }

    public void setDestPortString(String destPortString) {
	this.destPortString = destPortString;
    }

    public String getUserName() {
	return userName;
    }

    public void setUserName(String userName) {
	this.userName = userName;
    }

    public String getPassword() {
	return password;
    }

    public void setPassword(String password) {
	this.password = password;
    }

    public String formSendSMSURL(SMSMessage outMsg)
	    throws UnsupportedEncodingException {
	String to = outMsg.getDestAddr();
	String from = outMsg.getDestAddr();
	String text = java.net.URLEncoder.encode(outMsg.getText(), "UTF-8");
	String passEncoded = java.net.URLEncoder.encode(password, "UTF-8");

	// for Kannel the URL should be
	// http://smsbox.host.name:13013/cgi-bin/sendsms?username=foo&password=bar&to=0123456&text=Hello+world
	String url = "http://" + senderHostName + ":" + destPortString
		+ "/cgi-bin/sendsms?"
		+ "username="+userName + "&password="+passEncoded
		+ "&to=" + to + "&text=" + text;
	return url;

    }

    public static void usage() {
	System.out.println("Usage:  "
		+ "java org.ict4dlab.sms.adapters.http.SimpleGETAdapter "
		+ "<appClassname> <optional: localServerPort>");
    }

    public void start() {

	Handler handler = new SimpleGETServlet();
	Server server = new Server(localServerPort);
	server.setHandler(handler);
	try {
	    server.start();
	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

	// HttpServlet servlet = new SimpleGETServlet();
	// try {
	// ServletWebServer webServer = new ServletWebServer(servlet,
	// localServerPort);
	// webServer.start();
	// } catch (IOException ex) {
	// ex.printStackTrace();
	// } catch (ServletException ex) {
	// ex.printStackTrace();
	// }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
	if (args.length < 1) {
	    usage();
	    System.exit(-1);
	}

	SMSApplication newSMSApp = null;
	try {
	    newSMSApp = (SMSApplication) Class.forName(args[0]).newInstance();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	if (newSMSApp == null) {
	    System.exit(-2);
	}

	SimpleGETAdapter simpleTest = new SimpleGETAdapter(newSMSApp);
	simpleTest.start();
    }

    public static List HttpGet(URL url) throws IOException {
	// code taken from SMSLib org.smslib.http
	// exposed here since it's not public

	List responseList = new ArrayList();

	URLConnection con = url.openConnection();
	con.setAllowUserInteraction(false);
	BufferedReader in = new BufferedReader(new InputStreamReader(con
		.getInputStream()));
	String inputLine;
	while ((inputLine = in.readLine()) != null)
	    responseList.add(inputLine);
	in.close();
	return responseList;
    }

    public boolean sendSMSMessage(SMSMessage outgoingMsg) {
	try {
	    System.out.println( ">>> SENDING: sendSMSMessage via HTTP get " + outgoingMsg );
	    HttpGet(new URL(this.formSendSMSURL(outgoingMsg)));
	    return true;
	} catch (MalformedURLException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (UnsupportedEncodingException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return false;
    }

    // Inner class

    public class SimpleGETServlet extends AbstractHandler { // extends
	// HttpServlet {

	// @Override
	// protected void doGet(HttpServletRequest req, HttpServletResponse
	// resp)
	// throws ServletException, IOException {

	public void handle(String target, HttpServletRequest request,
		HttpServletResponse response, int dispatch) throws IOException {
	    String text = request.getParameter("text");
	    String srcAddr = request.getParameter("from");
	    String destAddr = request.getParameter("to");

	    SMSMessage inMsg = new SMSMessage(srcAddr, destAddr, text);
	    System.out.println( "Got incoming message: " + inMsg );
	    SMSMessage outMsg = smsApp.onSMSMessageReceived(inMsg);

	    if ((outMsg != null) && (outMsg.getDestAddr() != null)) {
		if (outMsg.getDestAddr().equalsIgnoreCase(inMsg.getSrcAddr())) {
		    // return recipient is the same as sender, then return via
		    // the servlet

		    System.out.println( ">>> RESPONDING to HTTP: " + outMsg );
		    
		    response.setContentType("text/html");
		    PrintWriter out = response.getWriter();
		    out.println(outMsg.getText());
		} else {
		    sendSMSMessage(outMsg);
		}
	    }
	    else
	    {
		System.out.println( "NULL response" );
	    }
	    ((Request) request).setHandled(true);

	}

    }
}
