package project.check;

import core.config.Factory;
import core.util.bean.Pair;
import online.context.check.ItemCheck;
import online.context.check.ItemCheckBase;
import online.context.check.KeepCheckException;
import online.context.check.NoMoreCheckException;
import project.common.master.Msg;
import project.master.MsgUtil;

/**
 * チェック親クラス
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public abstract class BaseCheck extends ItemCheckBase implements ItemCheck {

	/**
	 * チェック対象判断
	 *
	 * @param loc 位置
	 * @return チェック対象の場合 true を返す。
	 */
	protected final boolean isTarget(final int loc) {
		return super.getPredicate() == null || super.getPredicate().test(Integer.valueOf(loc));
	}

	/**
	 * トップメッセージ追加
	 *
	 * @param mid メッセージID
	 * @param prms パラメタ
	 */
	protected final void addTopMessage(final String mid, final String... prms) {
		Msg msg = Factory.create(Msg.class);
		super.getMessageList().add(msg.getMessage(mid, prms));
		super.getStatusList().add(msg.getStatus(mid));
	}

	/**
	 * メッセージ設定
	 * @param item 項目名
	 * @param loc 位置
	 * @param mid メッセージID
	 * @param prm メッセージパラメタ
	 */
	protected final void setMessage(final String item,
					final int loc, final String mid, final String... prm) {
		if (!MsgUtil.hasItemMessage(super.getUniModel(), item)) {
			addTopMessage(mid, prm);
		}
		if (!MsgUtil.hasItemMessage(super.getUniModel(), item, loc)) {
			MsgUtil.putItemMessage(super.getUniModel(), item, loc, mid, prm);
		}
	}

	/**
	 * 例外メッセージ取得
	 * @param item 項目名
	 * @param loc 位置
	 * @return 例外メッセージ
	 */
	private String getExceptionMessage(final String item, final Integer loc) {
		return String.join(":", this.getClass().getName(), item, String.valueOf(loc));
	}

	/**
	 * KeepCheckException
	 * @param p Pair
	 */
	protected final void throwKeepCheckException(final Pair<String, Integer> p) {
		throw new KeepCheckException(getExceptionMessage(p.left(), p.right()));
	}

	/**
	 * NoMoreCheckException
	 * @param p Pair
	 */
	protected final void throwNoMoreCheckException(final Pair<String, Integer> p) {
		throw new NoMoreCheckException(getExceptionMessage(p.left(), p.right()));
	}
}
