package online.filter.helper;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import core.config.Factory;

/**
 * アクションセションマップ
 *
 * @author Tadsahi Nakayama
 */
public class ActionSessionMap
				implements HttpSessionBindingListener, Map<String, Serializable>, Serializable {
	/** serialVersionUID */
	private static final long serialVersionUID = 1L;

	/** マップクラス */
	private final Map<String, Serializable> map = new HashMap<>();

	/**
	 * @see javax.servlet.http.HttpSessionBindingListener
	 * #valueBound(javax.servlet.http.HttpSessionBindingEvent)
	 */
	@Override
	public void valueBound(final HttpSessionBindingEvent arg0) {
		return;
	}

	/**
	 * @see javax.servlet.http.HttpSessionBindingListener
	 * #valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
	 */
	@Override
	public void valueUnbound(final HttpSessionBindingEvent arg0) {

		// タイムアウト処理クラス取得
		final var astl = Factory.create(ActionSessionTimeoutListener.class);
		if (astl != null) {
			for (final var ent : this.map.entrySet()) {
				astl.valueUnbound(ent.getValue());
			}
		}
	}

	/**
	 * @see java.util.Map#size()
	 */
	@Override
	public int size() {
		return this.map.size();
	}

	/**
	 * @see java.util.Map#clear()
	 */
	@Override
	public void clear() {
		this.map.clear();
	}

	/**
	 * @see java.util.Map#isEmpty()
	 */
	@Override
	public boolean isEmpty() {
		return this.map.isEmpty();
	}

	/**
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	@Override
	public boolean containsKey(final Object key) {
		return this.map.containsKey(String.class.cast(key));
	}

	/**
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	@Override
	public boolean containsValue(final Object value) {
		return this.map.containsValue(Serializable.class.cast(value));
	}

	/**
	 * @see java.util.Map#values()
	 */
	@Override
	public Collection<Serializable> values() {
		return this.map.values();
	}

	/**
	 * @see java.util.Map#putAll(java.util.Map)
	 */
	@Override
	public void putAll(final Map<? extends String, ? extends Serializable> t) {
		this.map.putAll(t);
	}

	/**
	 * @see java.util.Map#entrySet()
	 */
	@Override
	public Set<Entry<String, Serializable>> entrySet() {
		return this.map.entrySet();
	}

	/**
	 * @see java.util.Map#keySet()
	 */
	@Override
	public Set<String> keySet() {
		return this.map.keySet();
	}

	/**
	 * @see java.util.Map#get(java.lang.Object)
	 */
	@Override
	public Serializable get(final Object key) {
		return this.map.get(String.class.cast(key));
	}

	/**
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	@Override
	public Serializable remove(final Object key) {
		return this.map.remove(String.class.cast(key));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Serializable put(final String key, final Serializable value) {
		return this.map.put(key, value);
	}

	/**
	 * アクションセションタイムアウト
	 *
	 * @author Tadashi Nakayama
	 */
	public interface ActionSessionTimeoutListener {
		/**
		 * アンバウンド処理
		 *
		 * @param um アンバウンドモデル
		 */
		void valueUnbound(Serializable um);
	}
}
