package project.svc.generic;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import common.db.JdbcSource;
import common.db.jdbc.Jdbc;
import common.sql.QueryUtil;
import core.exception.PhysicalException;
import core.exception.ThrowableUtil;
import online.model.ModelUtil;
import online.model.UniModel;
import online.model.UniModelImpl;
import project.base.QueryAbstract;

/**
 * 更新サービス
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class UpdateService extends QueryAbstract {

	/** クエリファイル */
	private String query = null;
	/** 汎用モデル */
	private UniModel param = null;

	/**
	 * クエリファイル設定
	 * @param val クエリファイル
	 */
	public void setQueryFile(final String val) {
		this.query = val;
	}

	/**
	 * 汎用モデル設定
	 * @param val 汎用モデル
	 */
	public void setUniModel(final UniModel val) {
		this.param = val;
	}

	/**
	 * 配列項目更新
	 * @param main 主項目
	 * @return 更新件数
	 */
	public int updateArray(final String main) {
		UniModel um = new UniModelImpl();
		int length = this.param.getArraySize(main);
		int ret = 0;
		for (int i = 0; i < length; i++) {
			um.clear();
			for (final String key : this.param.keySet()) {
				if (this.param.getArraySize(key) == length) {
					ModelUtil.putRangeValueTo(um, this.param, key, i, i + 1);
				} else {
					this.param.putValueTo(um, key);
				}
			}
			ret += update(um);
		}
		return ret;
	}

	/**
	 * 更新処理
	 * @return 更新件数
	 */
	public int update() {
		return update(this.param);
	}

	/**
	 * 更新処理
	 * @param um パラメタモデル
	 * @return 更新件数
	 */
	private int update(final UniModel um) {
		String qry = QueryUtil.getSqlFromFile(this.query);
		if (!Objects.toString(qry, "").isEmpty()) {
			List<Object> qlist = new ArrayList<>();
			try (Jdbc conn = JdbcSource.getConnection(super.getSchema())) {
				try (PreparedStatement psmt = conn.prepareStatement(
						QueryUtil.toPrepareQuery(qry, super.toParamMap(um), qlist))) {
					int i = 1;
					for (final Object obj : qlist) {
						psmt.setObject(i++, obj);
					}
					return psmt.executeUpdate();
				}
			} catch (final SQLException ex) {
				ThrowableUtil.warn(ex);
				throw new PhysicalException(ex);
			}
		}
		return 0;
	}
}
