package project.base;

import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import common.db.JdbcSource;
import common.sql.QueryUtil;
import core.util.bean.CamelCase;
import online.context.session.SessionUser;

/**
 * クエリ作成用親
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public abstract class QueryAbstract extends ServiceAbstract {

	/** CamelCase */
	private final CamelCase cc = new CamelCase(true);
	/** エンコード */
	private Charset charset = JdbcSource.getCharset();
	/** スキーマ */
	private String schema;
	/** 画面ID */
	private String gid;
	/** 取得サイズ */
	private int fetchSize = 100;

	/**
	 * 取得サイズ設定
	 *
	 * @param val 取得サイズ
	 */
	public void setFetchSize(final int val) {
		this.fetchSize = val;
	}

	/**
	 * 取得サイズ取得
	 *
	 * @return 取得サイズ
	 */
	protected int getFetchSize() {
		return this.fetchSize;
	}

	/**
	 * エンコード設定
	 *
	 * @param val エンコード
	 */
	public void setCharset(final String val) {
		if (!Objects.toString(val, "").isEmpty()) {
			this.charset = Charset.forName(val);
		}
	}

	/**
	 * エンコード取得
	 *
	 * @return エンコード
	 */
	public Charset getCharset() {
		return this.charset;
	}

	/**
	 * 接続名設定
	 * @param val 接続名
	 */
	public void setSchema(final String val) {
		this.schema = val;
		this.charset = JdbcSource.getCharset(val);
	}

	/**
	 * 接続名取得
	 * @return 接続名
	 */
	protected String getSchema() {
		return this.schema;
	}

	/**
	 * 画面ID設定
	 * @param val 画面ID
	 */
	public void setGid(final String val) {
		this.gid = val;
	}

	/**
	 * ファイルからSQL取得
	 * @return SQL
	 */
	protected String getSqlFromFile() {
		return QueryUtil.getSqlFromFile(this.getClass().getName());
	}

	/**
	 * CamelCase化
	 * @param val 文字列
	 * @return CamelCase文字列
	 */
	protected String toCamelCase(final String val) {
		return this.cc.toCamelCase(val);
	}

	/**
	 * 共通パラメタ設定
	 * @param map パラメタマップ
	 * @return 設定マップ
	 */
	protected Map<String, Object> toParamMap(final Map<String, Serializable> map) {
		final var ret = new HashMap<String, Object>();
		if (map != null) {
			ret.putAll(map);
		}
		putCommonParameter(ret);
		return ret;
	}

	/**
	 * 共通パラメタ設定
	 * @param map 設定マップ
	 */
	protected void putCommonParameter(final Map<String, Object> map) {
		final var user = Optional.ofNullable(getSessionUser());
		map.putAll(user.map(SessionUser::getAttributeMap).orElse(Collections.emptyMap()));
		map.putAll(getProperty());
		map.put("Uid", getUid());
		map.put("DateTime", getDateTime());
		// TODO 権限設定（開示区分）
		map.put("Kaiji", this.gid);
	}
}
