package jp.sf.amateras.cookiesession.wrapper;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;

import jp.sf.amateras.cookiesession.cipher.Cipher;
import jp.sf.amateras.cookiesession.util.CookieSessionUtil;

public class CookieSessionRequest extends HttpServletRequestWrapper {

	private String cookieName;

	private CookieSession session;

	private Cipher chiper;

	private ServletContext context;

	private Map<String, Cookie> cookieMap;

	public CookieSessionRequest(HttpServletRequest request,
			String cookieName, Cipher chiper, ServletContext context) {
		super(request);
		this.cookieName = cookieName;
		this.chiper = chiper;
		this.context = context;
	}

	@Override
	public HttpSession getSession(boolean create) {
		if(session != null){
			return session;
		}

		String cookieValue = getCookieValue();
		if(cookieValue == null){
			if(create == false){
				return null;
			} else {
				session = new CookieSession(context, new HashMap<String, Object>(), true);
				return session;
			}
		}

		session = new CookieSession(null, CookieSessionUtil.decode(chiper, cookieValue), false);
		return session;
	}

	private String getCookieValue(){
		Map<String, Cookie> cookies = getSessionCookies();
		StringBuilder sb = new StringBuilder();
		int count = 1;
		while(true){
			Cookie cookie = cookies.get(cookieName + String.format("%02d", count));
			if(cookie == null){
				break;
			}
			sb.append(cookie.getValue());
			count++;
		}
		return sb.toString();
	}

	public Map<String, Cookie> getSessionCookies(){
		if(cookieMap == null){
			cookieMap = new HashMap<String, Cookie>();
			Cookie[] cookies = getCookies();
			if(cookies != null){
				for(Cookie cookie: cookies){
					if(cookie.getName().startsWith(cookieName)){
						cookieMap.put(cookie.getName(), cookie);
					}
				}
			}
		}
		return cookieMap;
	}

	@Override
	public HttpSession getSession() {
		return getSession(true);
	}

}
