package common.db.dao.hibernate;

import java.util.Optional;
import java.util.Properties;
import java.util.function.Function;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;

import core.config.Factory;

/**
 * 環境保持
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
final class Config {
	/** Configuration */
	private final Configuration configuration;
	/** SessionFactory */
	private final SessionFactory factory;
	/** Dialect */
	private final Dialect dialect;

	/**
	 * コンストラクタ
	 * @param cfg Configuration
	 * @param sf SessionFactory
	 */
	Config(final Configuration cfg, final SessionFactory sf) {
		this.configuration = cfg;
		this.factory = sf;
		this.dialect = getDialectInstance(cfg);
	}

	/**
	 * Dialectインスタンス取得
	 * @param cfg Configuration
	 * @return Dialectインスタンス
	 */
	private Dialect getDialectInstance(final Configuration cfg) {
		final Function<Properties, String> dlct = p -> p.getProperty(AvailableSettings.DIALECT);

		final String className = Optional.ofNullable(dlct.apply(cfg.getProperties())).
								orElseGet(() -> dlct.apply(Environment.getProperties()));
		return Factory.create(Factory.loadClass(className));
	}

	/**
	 * Configuration取得
	 * @return Configuration
	 */
	public Configuration getConfiguration() {
		return this.configuration;
	}

	/**
	 * SessionFactory取得
	 * @return SessionFactory
	 */
	public SessionFactory getSessionFactory() {
		return this.factory;
	}

	/**
	 * Dialect取得
	 * @return Dialect
	 */
	public Dialect getDialect() {
		return this.dialect;
	}
}
