/*
 *  Copyright (C) 2007  Takashi Kasuya <kasuya@sfc.keio.ac.jp>
 *
 * This library is free software; you can redistribute it and/or
 *　modify it under the terms of the GNU Lesser General Public
 *　License as published by the Free Software Foundation; either
 *　version 2.1 of the License, or (at your option) any later version.
 *　This library is distributed in the hope that it will be useful,
 *　but WITHOUT ANY WARRANTY; without even the implied warranty of
 *　MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *　Lesser General Public License for more details.
 *
 *　You should have received a copy of the GNU Lesser General Public
 *　License along with this library; if not, write to the Free Software
 *　Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

package jp.ac.naka.ec.plugin.http;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Stack;

import javax.sip.address.SipURI;

import jp.ac.naka.ec.Location;
import jp.ac.naka.ec.db.TupleSpaceAdapter;
import jp.ac.naka.ec.entity.Entity;
import jp.ac.naka.ec.entity.EntityEvent;
import jp.ac.naka.ec.entity.EntityImpl;
import jp.ac.naka.ec.entity.EntityEvent.EventType;
import jp.ac.naka.ec.sip.SipCore;

import org.apache.log4j.Logger;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.http.handler.AbstractHttpHandler;

/**
 * Ajax用のテストハンドラの実装。event/ajaxがイベント情報取得用のパス。
 * 
 * @author Takashi Kasuya
 * 
 */
class AjaxHandler extends AbstractHttpHandler implements HttpHandlerExt {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3390140933419713641L;
	private static Logger logger = Logger.getLogger(AjaxHandler.class);

	public static String VALUE_PARAM = "value";
	public static String TARGET_PARAM = "target";
	public static String AJAX_REQUEST_PATH = "/event/ajax";

	static TupleSpaceAdapter dispatcher = TupleSpaceAdapter.getInstance();

	private Entity source;

	public AjaxHandler() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mortbay.http.HttpHandler#handle(java.lang.String,
	 *      java.lang.String, org.mortbay.http.HttpRequest,
	 *      org.mortbay.http.HttpResponse)
	 */
	public void handle(String pathInContext, String pathParams,
			HttpRequest req, HttpResponse res) throws HttpException,
			IOException {
		if (!HttpRequest.__GET.equals(req.getMethod())
				&& !HttpRequest.__POST.equals(req.getMethod()))
			return;
		logger.info("Request to : " + pathInContext);
		String res_str = "YES";

		if (pathInContext.equals(AJAX_REQUEST_PATH)) {
			String target = req.getParameter(TARGET_PARAM);
			String value = req.getParameter(VALUE_PARAM);
			if (value != null) {
				// メッセージのブロードキャスト
				logger.info("Receive value : " + value);
				res_str = dispatchEvent(target, value, req);
			} else {
				// return xml for AJAX
				res_str = getResponseData(target, req);
			}
			if (res_str.equals(""))
				res_str = "<data>NO DATA</data>";
			BufferedOutputStream bos = new BufferedOutputStream(res
					.getOutputStream());
			// これをつけないとresponseXMLに入らなさげ
			res_str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + res_str;
			byte[] b = res_str.getBytes("UTF-8");
			bos.write(b, 0, b.length);
			bos.flush();
		}

	}

	/**
	 * 最新データだけの配信
	 * 
	 * @param target
	 * @param req
	 * @return
	 */
	private String getResponseData(String target, HttpRequest req) {
		int count = 0;
		String res_str = "";
		String temp = req.getParameter("count");
		if (temp != null) {
			count = Integer.valueOf(temp);
			// res_str = dispatcher.getDataByXML(target, count);

		} else {
			res_str = dispatcher.getDataByXML(target);
			if (res_str.equals("")) {
				// res_str = dispatcher.getDataByXML(target, 1);
			}
		}
		return res_str;
	}

	private String dispatchEvent(String target, String value, HttpRequest req) {

		EntityEvent evt = null;

		// 位置情報がついてくる場合
		String location_name, latitude, longitude;
		Location location = null;
		if ((location_name = req.getParameter("location")) != null
				&& (latitude = req.getParameter("latitude")) != null
				&& (longitude = req.getParameter("longitude")) != null) {
			location = new Location(location_name, latitude, longitude);
			source.setLocation(location);
		}
		if (target != null) {
			SipURI target_uri = null;
			target_uri = (SipURI) SipCore.getInstance().createURI(target);
			if (target_uri != null) {
				Entity e = new EntityImpl(target_uri);

				evt = new EntityEvent(value, e, source, EventType.MESSAGE);
			} else {
				return "Invalid URI :" + target;
			}
		} else {
			// Broadcast message
			evt = new EntityEvent(value, null, source);
			evt.setBroadcast(true);
		}
		if (evt != null) {
			if (evt.isBroadcast())
				logger.info("Dispatch Event by Broadcast.");
			else
				logger.info("Dispatch Event to " + target);

			dispatcher.dispatchEvent(evt);
		}
		return "<data>YES</data>";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jp.ac.naka.ec.plugin.http.HttpHandlerExt#setSourceEntity(jp.ac.naka.ec.entity.Entity)
	 */
	public void setSourceEntity(Entity source) {
		this.source = source;
	}
}