package thermalmap;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.jdo.PersistenceManager;
import javax.servlet.http.*;

@SuppressWarnings("serial")
public class ThermalMapServlet extends HttpServlet {
	static long __lastDelTime = 0L;

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
//		resp.setContentType("text/plain");
//		resp.getWriter().println("Hello, world");
		doPost(req, resp);
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		if ( (System.currentTimeMillis() - __lastDelTime) > 1000*60 ){		// １分以内は行わない
			delete();
			__lastDelTime = System.currentTimeMillis();
		}

		String lat = req.getParameter("lat");			// 位置情報がないなら登録しない（参照は可能）
		String lon = req.getParameter("lon");
		if ( (lat != null) && lat.length() != 0 && (lon != null) && lon.length() != 0 ){
			add(req);
		}

		String output = req.getParameter("output");
		if ( (output != null) && output.equalsIgnoreCase("text") ){
	        responseText(req, resp);
		} else {
			responseHtml(req, resp);
		}
	}

	public void responseText(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.JAPAN);

		String area = req.getParameter("area");
		// 現在時刻 － 何時間前まで有効 ＝ 有効になる時間（これ以降の時間が有効）
		long hist = System.currentTimeMillis() - (Long.parseLong(req.getParameter("hist")) * 60 * 1000);
		int strong = Integer.parseInt(req.getParameter("strong"));
		Double alt = null;
		if ( req.getParameter("alt") != null && req.getParameter("alt").length() != 0 && !req.getParameter("alt").equals("null") ){
			alt = Double.parseDouble(req.getParameter("alt"));
		}
		int range = Integer.parseInt(req.getParameter("range"));

		resp.setContentType("text/plain; charset=UTF-8");

		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String query = "select from " + Thermal.class.getName()+ " order by time desc";
			List<Thermal> thermals = (List<Thermal>) pm.newQuery(query).execute();
			if (!thermals.isEmpty()) {
				for (Thermal g : thermals) {
					if ( !( g.getArea().equals(area) ) ){			// 同じエリアだけ
						continue;
					}
					if ( g.getTime() < hist ){						// 指定の時間前までの
						continue;
					}
					String strInc = g.getInc();						// 指定のサーマルの強さ以上の
					if ( strInc != null && strInc.length() != 0 ){
						if ( Double.parseDouble(strInc) < strong ){
							continue;
						}
					}
					if ( alt != null ){								// 指定の高度範囲の
						String strAlt = g.getAlt();
						if ( alt - range > Double.parseDouble(strAlt) || alt + range < Double.parseDouble(strAlt) ){
							continue;
						}
					}
					resp.getWriter().print(g.getId() + "\t");
					resp.getWriter().print(g.getArea() + "\t");
					resp.getWriter().print(g.getDevid() + "\t");
					resp.getWriter().print(g.getLat() + "\t");
					resp.getWriter().print(g.getLon() + "\t");
					resp.getWriter().print(g.getAlt() + "\t");
					resp.getWriter().print(g.getInc() + "\t");
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue() + 9 * 60 * 60 * 1000;
					}
					resp.getWriter().print(sdf.format(new Date(t)) + "\n");
			    }
			}

			query = "select from " + Glider.class.getName()+ " order by time desc";
			List<Glider> gliders = (List<Glider>) pm.newQuery(query).execute();
			if (!gliders.isEmpty()) {
				for (Glider g : gliders) {
					if ( !( g.getArea().equals(area) ) ){			// 同じエリアだけ
						continue;
					}
					resp.getWriter().print(g.getId() + "\t");
					resp.getWriter().print(g.getArea() + "\t");
					resp.getWriter().print(g.getDevid() + "\t");
					resp.getWriter().print(g.getLat() + "\t");
					resp.getWriter().print(g.getLon() + "\t");
					resp.getWriter().print(g.getAlt() + "\t");
					resp.getWriter().print("*\t");
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue() + 9 * 60 * 60 * 1000;
					}
					resp.getWriter().print(sdf.format(new Date(t)) + "\n");
			    }
			}
		} finally {
		    pm.close();
		}
	}
	public void responseHtml(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.JAPAN);

		String area = req.getParameter("area");
		// 現在時刻 － 何時間前まで有効 ＝ 有効になる時間（これ以降の時間が有効）
		long hist = System.currentTimeMillis() - (Long.parseLong(req.getParameter("hist")) * 60 * 1000);
		int strong = Integer.parseInt(req.getParameter("strong"));
		Double alt = null;
		if ( req.getParameter("alt") != null && req.getParameter("alt").length() != 0 && !req.getParameter("alt").equals("null") ){
			alt = Double.parseDouble(req.getParameter("alt"));
		}
		int range = Integer.parseInt(req.getParameter("range"));

		resp.setContentType("text/html; charset=UTF-8");
		resp.getWriter().println("<HTML><HEAD>");
		resp.getWriter().println("<TITLE>データ一覧</TITLE>");
		resp.getWriter().println("</HEAD><BODY>");
		resp.getWriter().println("<p>データ一覧</p>");
		resp.getWriter().println("User-Agent:" + req.getHeader("User-Agent"));
		resp.getWriter().println("<table border=\"1\" cellpadding=\"2\" style=\"border-collapse:collapse\">");
		resp.getWriter().println("<tr><th>ID</th><th>エリア</th><th>デバイスID</th><th>緯度</th><th>経度</th><th>高度</th><th>上昇率</th><th>時刻</th></tr>");

		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String query = "select from " + Thermal.class.getName()+ " order by time desc";
			List<Thermal> thermals = (List<Thermal>) pm.newQuery(query).execute();
			if (!thermals.isEmpty()) {
				for (Thermal g : thermals) {
					if ( !( g.getArea().equals(area) ) ){			// 同じエリアだけ
						continue;
					}
					if ( g.getTime() < hist ){						// 指定の時間前までの
						continue;
					}
					String strInc = g.getInc();						// 指定のサーマルの強さ以上の
					if ( strInc != null && strInc.length() != 0 ){
						if ( Double.parseDouble(strInc) < strong ){
							continue;
						}
					}
					if ( alt != null ){								// 指定の高度範囲の
						String strAlt = g.getAlt();
						if ( alt - range > Double.parseDouble(strAlt) || alt + range < Double.parseDouble(strAlt) ){
							continue;
						}
					}
					resp.getWriter().println("<tr>");
					resp.getWriter().println("<th>" + g.getId() + "</th>");
					resp.getWriter().println("<th>" + g.getArea() + "</th>");
					resp.getWriter().println("<th>" + g.getDevid() + "</th>");
					resp.getWriter().println("<th>" + g.getLat() + "</th>");
					resp.getWriter().println("<th>" + g.getLon() + "</th>");
					resp.getWriter().println("<th align=\"right\">" + g.getAlt() + "</th>");
					resp.getWriter().println("<th align=\"right\">" + g.getInc() + "</th>");
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue() + 9 * 60 * 60 * 1000;
					}
					resp.getWriter().println("<th>" + sdf.format(new Date(t)) + "</th>");
					resp.getWriter().println("</tr>");
			    }
			}

			query = "select from " + Glider.class.getName()+ " order by time desc";
			List<Glider> gliders = (List<Glider>) pm.newQuery(query).execute();
			if (!gliders.isEmpty()) {
				for (Glider g : gliders) {
					if ( !( g.getArea().equals(area) ) ){			// 同じエリアだけ
						continue;
					}
					resp.getWriter().println("<tr>");
					resp.getWriter().println("<th>" + g.getId() + "</th>");
					resp.getWriter().println("<th>" + g.getArea() + "</th>");
					resp.getWriter().println("<th>" + g.getDevid() + "</th>");
					resp.getWriter().println("<th>" + g.getLat() + "</th>");
					resp.getWriter().println("<th>" + g.getLon() + "</th>");
					resp.getWriter().println("<th align=\"right\">" + g.getAlt() + "</th>");
					resp.getWriter().println("<th align=\"right\">*</th>");
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue() + 9 * 60 * 60 * 1000;
					}
					resp.getWriter().println("<th>" + sdf.format(new Date(t)) + "</th>");
					resp.getWriter().println("</tr>");
			    }
			}
		} finally {
		    pm.close();
		}
		resp.getWriter().println("</BODY></HTML>");
	}

	public void add(HttpServletRequest req) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String alt = req.getParameter("alt");
			String inc = req.getParameter("inc");
			if ( (alt != null) && alt.length() != 0			// 高度、上昇率がないならサーマル情報に入れない
			  && (inc != null) && inc.length() != 0 ){		// 
				int nInc = (int)Double.parseDouble(inc);
				if ( nInc > 1 && nInc < 10 ){				// +1以上+9までにする、それ以外は異常データ
					Thermal thermal = new Thermal();
					thermal.setTime(System.currentTimeMillis());
					thermal.setArea(req.getParameter("area"));
					thermal.setDevid(req.getParameter("devid"));
					thermal.setLat(req.getParameter("lat"));
					thermal.setLon(req.getParameter("lon"));
					thermal.setAlt(alt);
					thermal.setInc(inc);
					pm.makePersistent(thermal);
				}
			}
			Glider glider = null;
			String query = "select from " + Glider.class.getName()+ " order by time asc";
			List<Glider> gliders = (List<Glider>) pm.newQuery(query).execute();
			if ( !gliders.isEmpty() ) {
				for (Glider g : gliders) {
					if (g.getDevid().equals(req.getParameter("devid"))){
						Long id = g.getId();
						glider = pm.getObjectById(Glider.class, id);
						glider.setTime(System.currentTimeMillis());
						glider.setLat(req.getParameter("lat"));
						glider.setLon(req.getParameter("lon"));
						glider.setAlt(req.getParameter("alt"));
						break;
					}
			    }
			}
			if ( glider == null ) {
				glider = new Glider();
				glider.setTime(System.currentTimeMillis());
				glider.setArea(req.getParameter("area"));
				glider.setDevid(req.getParameter("devid"));
				glider.setLat(req.getParameter("lat"));
				glider.setLon(req.getParameter("lon"));
				glider.setAlt(req.getParameter("alt"));
			}
			pm.makePersistent(glider);
		} finally {
			pm.close();
		}
	}
	public void delete() {
		deleteThermal(1000*60*60*48);	// ４８時間で削除
		deleteGlider(1000*60);			// １分で削除
	}
	public static void deleteThermal(long delay) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String query = "select from " + Thermal.class.getName()+ " order by time asc";
			List<Thermal> thermals = (List<Thermal>) pm.newQuery(query).execute();
			if ( !thermals.isEmpty() ) {
				for (Thermal g : thermals) {
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue();
					}
					if ( (System.currentTimeMillis() - t) > delay ){
						Long id = g.getId();
						Thermal data = pm.getObjectById(Thermal.class, id);
						pm.deletePersistent(data);
					} else {
						break;
					}
			    }
			}
		} finally {
			pm.close();
		}
	}
	public static void deleteGlider(long delay) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String query = "select from " + Glider.class.getName()+ " order by time asc";
			List<Glider> gliders = (List<Glider>) pm.newQuery(query).execute();
			if ( !gliders.isEmpty() ) {
				for (Glider g : gliders) {
					long t = 0;
					Long time = g.getTime();
					if ( time != null){
						t = time.longValue();
					}
					if ( (System.currentTimeMillis() - t) > delay ){
						Long id = g.getId();
						Glider data = pm.getObjectById(Glider.class, id);
						pm.deletePersistent(data);
					} else {
						break;
					}
			    }
			}
		} finally {
			pm.close();
		}
	}
}
