package org.clubrockisen.dao.h2;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.clubrockisen.common.Configuration;
import org.clubrockisen.common.ConfigurationKey;
import org.clubrockisen.common.error.SQLConfigurationError;
import org.clubrockisen.dao.Utils;
import org.clubrockisen.dao.Utils.DBConnectionInfo;
import org.clubrockisen.dao.abstracts.AbstractDAOFactory;
import org.clubrockisen.dao.abstracts.DAO;
import org.clubrockisen.dao.mysql.MySQLEntryMemberPartyDAO;
import org.clubrockisen.dao.mysql.MySQLMemberDAO;
import org.clubrockisen.dao.mysql.MySQLParameterDAO;
import org.clubrockisen.dao.mysql.MySQLPartyDAO;
import org.clubrockisen.entities.EntryMemberParty;
import org.clubrockisen.entities.Member;
import org.clubrockisen.entities.Parameter;
import org.clubrockisen.entities.Party;
import org.h2.engine.Constants;
import org.h2.tools.RunScript;

/**
 * TODO
 * @author Alex
 */
public class H2DAOFactory extends AbstractDAOFactory {
	/** Logger */
	private static Logger	lg	= Logger.getLogger(H2DAOFactory.class.getName());
	
	/** Access to the configuration */
	private final Configuration			config	= Configuration.getInstance();
	/** Access to the key structure of the configuration */
	private final ConfigurationKey		keys	= ConfigurationKey.KEY;
	/** The connection to the database */
	private final Connection			connection;
	/** The member DAO */
	private final DAO<Member>			memberDao;
	/** The parameter DAO */
	private final DAO<Parameter>		parameterDao;
	/** The party DAO */
	private final DAO<Party>			partyDao;
	/** The party DAO */
	private final DAO<EntryMemberParty>	entryMemberPartyDao;
	
	/**
	 * Constructor #1.<br />
	 */
	public H2DAOFactory () {
		super();
		
		final DBConnectionInfo dbInfos = Utils.getConnectionInfo();
		Path dbFile = getDBFile(dbInfos, true);
		if (!Files.exists(dbFile)) {
			try {
				dbFile = getDBFile(dbInfos, false);
				if (lg.isLoggable(Level.INFO)) {
					lg.info("URL connection: " + (Constants.START_URL + dbFile));
				}
				RunScript.execute(Constants.START_URL + dbFile, dbInfos.getUsername(), dbInfos.getPassword(),
						config.get(keys.db().creationFile()), null, true);
			} catch (final SQLException e) {
				lg.warning("Error while initilization of H2 database (" + e.getClass() + "; " +
						e.getMessage() + ")");
				throw new SQLConfigurationError("Could not create H2 database", e);
			}
			
		}
		
		connection = Utils.getConnection();
		
		// TODO DAOs
		memberDao = new MySQLMemberDAO(connection);
		parameterDao = new MySQLParameterDAO(connection);
		partyDao = new MySQLPartyDAO(connection);
		entryMemberPartyDao = new MySQLEntryMemberPartyDAO(connection);
	}
	
	/**
	 * Check if the database file exists.
	 * @param dbInfos
	 *        the database information to use.
	 * @param suffix
	 *        <code>true</code> if the suffix should be added to the path.
	 * @return <code>true</code>
	 */
	private static Path getDBFile (final DBConnectionInfo dbInfos, final boolean suffix) {
		// Creating database if file does not exists. jdbc:h2:file:data/database/crock.db
		String file = dbInfos.getUrl().substring(Constants.START_URL.length());
		if (file.startsWith("file:")) {
			file = file.substring("file:".length());
		}
		// Removing parameters
		final int delimiter = file.lastIndexOf(';');
		if (delimiter >= 0) {
			file = file.substring(0, delimiter);
		}
		
		// Adding the extension if required
		if (suffix) {
			file += Constants.SUFFIX_PAGE_FILE;
		}
		
		if (lg.isLoggable(Level.FINE)) {
			lg.fine("filename: " + file);
		}
		return Paths.get(file);
	}
	
	/* (non-Javadoc)
	 * @see java.io.Closeable#close()
	 */
	@Override
	public void close () throws IOException {
		Utils.close(connection);
	}
	
	/* (non-Javadoc)
	 * @see org.clubrockisen.dao.abstracts.AbstractDAOFactory#getParameterDAO()
	 */
	@Override
	public DAO<Parameter> getParameterDAO () {
		return parameterDao;
	}
	
	/* (non-Javadoc)
	 * @see org.clubrockisen.dao.abstracts.AbstractDAOFactory#getMemberDAO()
	 */
	@Override
	public DAO<Member> getMemberDAO () {
		return memberDao;
	}
	
	/* (non-Javadoc)
	 * @see org.clubrockisen.dao.abstracts.AbstractDAOFactory#getPartyDAO()
	 */
	@Override
	public DAO<Party> getPartyDAO () {
		return partyDao;
	}
	
	/* (non-Javadoc)
	 * @see org.clubrockisen.dao.abstracts.AbstractDAOFactory#getEntryMemberPartyDAO()
	 */
	@Override
	public DAO<EntryMemberParty> getEntryMemberPartyDAO () {
		return entryMemberPartyDao;
	}
}

@@ -1095,19 +1095,242 @@
 **%0D%0A * T
-ODO
+he factory for the H2 DAO classes.%3Cbr /%3E%0D%0A * A factory is only handling one DAO of each type and thus will not instantiate more DAOs than%0D%0A * needed. However, if the factory is load several times, several DAOs will be created.
 %0D%0A * @au
@@ -1413,24 +1413,24 @@
  Logger */%0D%0A
-
 %09private sta
@@ -1440,16 +1440,19 @@
  Logger%09
+%09%09%09
 lg%09= Log

Complete Javadoc for H2 DAO Factory.