package project.batch;

import java.util.Objects;

import org.apache.logging.log4j.LogManager;

import batch.base.Batch;
import batch.base.BatchStatus;
import core.config.Env;
import core.config.Factory;
import project.common.master.Msg;

/**
 * バッチステータス
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class BatStatus {

	/** バッチ処理　DBテーブル更新時メッセージコード */
	public static final String MSGID_UPD = "Message.UPD_RECORD";
	/** バッチ処理　DBテーブル登録時メッセージコード */
	public static final String MSGID_INS = "Message.INS_RECORD";
	/** バッチ処理　DBテーブル削除時メッセージコード */
	public static final String MSGID_DEL = "Message.DEL_RECORD";
	/** バッチ処理　DBテーブル読込時メッセージコード */
	public static final String MSGID_SEL = "Message.SEL_RECORD";
	/** バッチ処理　ファイル出力時メッセージコード */
	public static final String MSGID_WRI = "Message.WRI_FILE";
	/** バッチ処理　ファイル読込時メッセージコード */
	public static final String MSGID_RED = "Message.RED_FILE";
	/** バッチ処理　ファイル削除時メッセージコード */
	public static final String MSGID_RMV = "Message.RMV_FILE";

	/** ジョブステータス */
	private final BatchStatus status = new BatchStatus();

	/**
	 * コンストラクタ
	 */
	private BatStatus() {
		super();
	}

	/**
	 * バッチmain処理
	 *
	 * @param args 起動パラメタ
	 */
	public static void main(final String... args) {
		final var ret = new BatStatus().perform(args);
		Runtime.getRuntime().exit(ret);
	}

	/**
	 * 処理実行
	 *
	 * @param args 引数
	 * @return 処理結果
	 */
	private int perform(final String... args) {
		var ret = Batch.RET_SUCCESS;
		try {
			// 引数チェック
			final var prms = this.status.checkArgs(args);

			final var pp = new ProjectParameter();
			pp.setCommandParameter(args);
			this.status.setUid(pp.getUid());

			if (BatchStatus.JOB_START.equals(args[0])) {
				// ジョブ管理状態確認
				ret = checkJobStart(prms);
			} else if (BatchStatus.JOB_CONT.equals(args[0])) {
				// ジョブ詳細管理状態確認
				ret = checkLastJobDetail(prms);
			} else if (BatchStatus.JOB_END.equals(args[0])) {
				// ジョブ詳細管理状態確認
				ret = checkAllJobDetail(prms);
			} else {
				// バッチジョブクリア
				this.status.clearJob();
				// 処理結果出力
				final var msg = Factory.create(Msg.class);
				final var list = this.status.getCleared();
				if (0 < list.size()) {
					LogManager.getLogger().fatal(msg.getMessage(Env.getEnv(MSGID_DEL),
							Env.getEnv("JobStatus.Table"), Objects.toString(list.get(0), "")));
				}
				if (1 < list.size()) {
					LogManager.getLogger().fatal(msg.getMessage(Env.getEnv(MSGID_DEL),
							Env.getEnv("JobDetail.Table"), Objects.toString(list.get(1), "")));
				}
				if (2 < list.size()) {
					LogManager.getLogger().fatal(msg.getMessage(Env.getEnv(MSGID_DEL),
							Env.getEnv("JobFile.Table"), Objects.toString(list.get(2), "")));
				}
				if (3 < list.size()) {
					LogManager.getLogger().fatal(msg.getMessage(Env.getEnv(MSGID_RMV),
							"", Objects.toString(list.get(3), "")));
				}
			}

		} catch (final IllegalArgumentException ex) {
			LogManager.getLogger().info(ex.getMessage());
			BatchStatus.printUsage(this.getClass().getName());
			Runtime.getRuntime().exit(Batch.RET_PARAM_ERROR);
		}

		return ret;
	}

	/**
	 * 開始状態チェック
	 *
	 * @param prms パラメタ
	 * @return バッチ終了ステータス
	 */
	private int checkJobStart(final String... prms) {
		var ret = Batch.RET_SUCCESS;
		try {
			ret = this.status.checkJobStart(prms);
			return ret;
		} finally {
			LogManager.getLogger().fatal(getMessageHeader()
					+ ",,Start,ジョブが開始しました。" + getMessageResult(ret));
		}
	}

	/**
	 * ジョブ継続処理
	 *
	 * @param prms パラメタ
	 * @return バッチ終了ステータス
	 */
	private int checkLastJobDetail(final String... prms) {
		int ret = Batch.RET_SUCCESS;
		try {
			ret = this.status.checkLastJobDetail(prms);
			return ret;
		} finally {
			LogManager.getLogger().fatal(getMessageHeader()
					+ ",,Continue,ジョブが継続しました。" + getMessageResult(ret));
		}
	}

	/**
	 * ジョブ終了処理
	 *
	 * @param prms パラメタ
	 * @return バッチ終了ステータス
	 */
	private int checkAllJobDetail(final String... prms) {
		int ret = Batch.RET_SUCCESS;
		try {
			ret = this.status.checkAllJobDetail(prms);
			return ret;
		} finally {
			LogManager.getLogger().fatal(getMessageHeader()
					+ ",,End,全ジョブが終了しました。" + getMessageResult(ret));
		}
	}

	/**
	 * メッセージヘッダ取得
	 *
	 * @return メッセージヘッダ
	 */
	private String getMessageHeader() {
		return String.join(
				",", this.status.getUid(), this.status.getIp(), this.status.getJobId());
	}

	/**
	 * メッセージステータス取得
	 *
	 * @param ret 復帰値
	 * @return メッセージステータス
	 */
	private String getMessageResult(final int ret) {
		return "(ret=" + ret + ", jobseq=" + this.status.getJobSeq() + ")";
	}
}
