package com.shin1ogawa.servlet;

import java.io.IOException;
import java.util.Collections;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.google.appengine.api.users.UserServiceFactory;
import com.shin1ogawa.entity.Board;
import com.shin1ogawa.service.BoardService;

@SuppressWarnings("serial")
public class GetBoard extends HttpServlet {

	BoardService service = new BoardService();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String id = req.getParameter("id");
		if (StringUtils.isNotEmpty(id)) {
			Board board = getBoard(Long.parseLong(id));
			req.setAttribute("user", UserServiceFactory.getUserService()
					.getCurrentUser());
			req.setAttribute("loginUrl", UserServiceFactory.getUserService()
					.createLoginURL(req.getRequestURI()));
			req.setAttribute("logoutUrl", UserServiceFactory.getUserService()
					.createLogoutURL(req.getRequestURI()));
			req.setAttribute("board", board);
			req.setAttribute("noMessages", board.getMessages().isEmpty());
			req.getRequestDispatcher("/board.jsp").forward(req, resp);
		} else {
			resp.sendRedirect("/");
		}
	}

	/**
	 * 指定されたIDに対応するBoardを返す。
	 * <p>
	 * キャッシュがあればそれを使用し、キャッシュがなければDBから取得してキャッシュする。
	 * </p>
	 * 
	 * @param id
	 *            {@link Board#getId()}
	 * @return 指定されたIDに対応するBoard
	 */
	@SuppressWarnings("unchecked")
	private Board getBoard(Long id) {
		String key = Board.class.getName() + "\\" + id;
		Cache cache = null;
		try {
			cache = CacheManager.getInstance().getCacheFactory().createCache(
					Collections.emptyMap());
			if (cache.containsKey(key)) {
				return (Board) cache.get(key);
			}
		} catch (CacheException e) {
			//
		}
		Board board = service.getById(id);
		if (cache != null) {
			cache.put(key, board);
		}
		return board;
	}
}
