/*
 Storybook: Open Source software for novelists and authors.
 Copyright (C) 2008 - 2012 Martin Mustun

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package storybook.model.hbn;

import com.googlecode.genericdao.dao.hibernate.GenericDAOImpl;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import storybook.model.hbn.entity.AbstractEntity;
import storybook.tools.LOG;

public class SbSessionFactory {

	private static final String TT = "SbSessionFactory";

	private SessionFactory sessionFactory;

	public SbSessionFactory() {
		// empty
	}

	public SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			LOG.err("*** Call " + TT + ".init() first.");
		}
		return sessionFactory;
	}

	public Session getSession() {
		if (sessionFactory == null) {
			LOG.err("*** Call " + TT + ".init() first.");
			return null;
		}
		return sessionFactory.getCurrentSession();
	}

	public void init(String filename) {
		//LOG.trace(TT+".init()");
		try {
			Configuration config = new Configuration();
			config.setProperty("hibernate.show_sql", "false");
			config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
			config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
			String dbURL = "jdbc:h2:" + filename
				+ ";TRACE_LEVEL_FILE=" + (LOG.getTraceHibernate() ? "3" : "0")
				+ ";TRACE_LEVEL_SYSTEM_OUT=" + (LOG.getTraceHibernate() ? "3" : "0");
			config.setProperty("hibernate.connection.url", dbURL);
			config.setProperty("hibernate.connection.username", "sa");
			config.setProperty("hibernate.connection.password", "");
			config.setProperty("hibernate.hbm2ddl.auto", "update");
			config.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
			config.setProperty("current_session_context_class", "thread");
			config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider");
			config.setProperty("hibernate.current_session_context_class", "thread");

			config.addClass(storybook.model.hbn.entity.Attribute.class);
			config.addClass(storybook.model.hbn.entity.Category.class);
			config.addClass(storybook.model.hbn.entity.Chapter.class);
			config.addClass(storybook.model.hbn.entity.Endnote.class);
			config.addClass(storybook.model.hbn.entity.Episode.class);
			config.addClass(storybook.model.hbn.entity.Gender.class);
			config.addClass(storybook.model.hbn.entity.Idea.class);
			config.addClass(storybook.model.hbn.entity.Internal.class);
			config.addClass(storybook.model.hbn.entity.Location.class);
			config.addClass(storybook.model.hbn.entity.Part.class);
			config.addClass(storybook.model.hbn.entity.Person.class);
			config.addClass(storybook.model.hbn.entity.Plot.class);
			config.addClass(storybook.model.hbn.entity.Relationship.class);
			config.addClass(storybook.model.hbn.entity.Status.class);
			config.addClass(storybook.model.hbn.entity.Strand.class);
			config.addClass(storybook.model.hbn.entity.Event.class);
			config.addClass(storybook.model.hbn.entity.AbstractTag.class);
			config.addClass(storybook.model.hbn.entity.AbstractTaglink.class);
			config.addClass(storybook.model.hbn.entity.Scene.class);
			sessionFactory = config.buildSessionFactory();
		} catch (SecurityException | HibernateException ex) {
			LOG.err(TT + ".init() *** Initial SessionFactory creation failed: ", ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public void test(GenericDAOImpl<? extends AbstractEntity, ?> dao) {
		//LOG.trace(TT+".test(dao=" + dao.getClass().getSimpleName()+")");
		List<? extends AbstractEntity> entities = dao.findAll();
		for (AbstractEntity entity : entities) {
			String name = entity.getClass().getSimpleName();
		}
	}

	public void closeSession() {
		sessionFactory.close();
	}
}
