package online.struts.action;

import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import online.model.ModelUtil;
import online.struts.mapping.RequestMapping;

import org.apache.logging.log4j.LogManager;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 * Performアクション
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public interface PerformAction extends Action {

	/** ビュー */
	String ID_VIEW = "VIEW";
	/** ID OK */
	String ID_OK = "OK";
	/** ID NG */
	String ID_NG = "NG";

	/**
	 * @see org.apache.struts.action.Action
	 * #execute(org.apache.struts.action.ActionMapping,
	 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse)
	 */
	@Override
	default ActionForward execute(final ActionMapping mapping, final ActionForm form,
			final HttpServletRequest request, final HttpServletResponse response) {
		if (!RequestMapping.class.isInstance(mapping)) {
			LogManager.getLogger().error(mapping);
			throw new IllegalArgumentException();
		}
		final var rm = RequestMapping.class.cast(mapping);

		// フォームキャスト
		if (!UniForm.class.isInstance(form)) {
			LogManager.getLogger().error(form);
			throw new IllegalArgumentException();
		}
		final var uf = UniForm.class.cast(form);

		// アクション呼出
		uf.remove(ModelUtil.TAG_RETURN);
		final var ret = perform(rm, uf, request, response);
		if (!uf.containsKey(ModelUtil.TAG_RETURN)) {
			uf.setValue(ModelUtil.TAG_RETURN, ret);
		}
		final var af = mapping.findForward(ret);
		return Optional.ofNullable(af).orElse(new ActionForward(ret, null, false));
	}

	/**
	 * 従処理
	 *
	 * @param mapping ActionMappingオブジェクト
	 * @param uf 汎用フォーム
	 * @param request HttpServletRequestオブジェクト
	 * @param response HttpServletResponseオブジェクト
	 * @return 処理結果
	 */
	String perform(RequestMapping mapping, UniForm uf,
			HttpServletRequest request, HttpServletResponse response);
}
