package online.view.model;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import javax.servlet.ServletResponse;

import online.model.UniModel;
import online.view.ViewUtil;
import core.config.Factory;

/**
 * 表示用マップ
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
final class UnsanitaryMap implements ViewMap {
	/** serialVersionUID */
	private static final long serialVersionUID = -8472914252088857480L;

	/** モデル */
	private Serializable model = null;
	/** レスポンス */
	private transient ServletResponse response;
	/** マッピング */
	private String mapping = null;

	/**
	 * モデル取得
	 * @return モデル
	 */
	@Override
	public Map<String, Serializable> getMap() {
		return Factory.cast(this.model);
	}

	/**
	 * マップ設定
	 *
	 * @param val マップオブジェクト
	 */
	@Override
	public void setMap(final Map<String, Serializable> val) {
		if (this.model == null) {
			this.model = Factory.cast(val);
		}
	}

	/**
	 * レスポンス設定
	 *
	 * @param val レスポンス
	 */
	@Override
	public void setResponse(final ServletResponse val) {
		this.response = val;
	}

	/**
	 * マッピング取得
	 *
	 * @return マッピング
	 */
	private String getMapping() {
		if (this.mapping == null) {
			this.mapping = ViewUtil.getMapping(this.response);
		}
		return this.mapping;
	}

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

	/**
	 * @see java.util.Map#clear()
	 */
	@Override
	public void clear() {
		throw new UnsupportedOperationException();
	}

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

	/**
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	@Override
	public boolean containsKey(final Object key) {
		return getMap().containsKey(Objects.toString(key, null));
	}

	/**
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	@Override
	public boolean containsValue(final Object value) {
		throw new UnsupportedOperationException();
	}

	/**
	 * @see java.util.Map#values()
	 */
	@Override
	public Collection<Serializable> values() {
		throw new UnsupportedOperationException();
	}

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

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

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

	/**
	 * @see java.util.Map#get(java.lang.Object)
	 */
	@Override
	public Serializable get(final Object key) {
		Serializable obj = getMap().get(key);
		if (obj != null) {
			if (obj.getClass().isArray()) {
				obj = new ViewList(Arrays.asList(
						Serializable[].class.cast(obj)), getMapping(), false);
			} else if (UniModel.class.isInstance(obj)) {
				obj = null;
			}
		}
		return obj;
	}

	/**
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	@Override
	public Serializable remove(final Object key) {
		throw new UnsupportedOperationException();
	}

	/**
	 * @param key キー
	 * @param value 値
	 * @return 既存値
	 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
	 */
	@Override
	public Serializable put(final String key, final Serializable value) {
		throw new UnsupportedOperationException();
	}
}
