package de.hsadmin.mods.db;

import javax.persistence.EntityManager;

import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;

/** Factory class which creates Processor instances for dealing with UNIX user accounts.
 * 
 * @author mi
 */ 
public class MySqlDatabaseProcessorFactory implements EntityProcessorFactory {
	/// creates a JDBCProcessor for MySQL and the given user
	public static JDBCProcessor createMySqlProcessor( String database, String user, String password )
	{
		return new JDBCProcessor( "com.mysql.jdbc.Driver",
				"jdbc:mysql://localhost/" + database,
				user, password );
	}

	/// creates a JDBCProcessor for the MySQL admin user
	public static JDBCProcessor createMySqlAdminProcessor()
	{
		return new JDBCProcessor( "com.mysql.jdbc.Driver", "jdbc:mysql://localhost/" );
	}
	
	/// @return a Processor which creates a new database
	public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity)
	{
		Database db = (Database) entity;
		assert db.getInstance().equals("mysql");
		
		JDBCProcessor aJDBCP = null;
		String aName = AbstractEntity.escapeString( db.getName() );
		String aOwner = AbstractEntity.escapeString( db.getOwner() );
		String aEncoding = AbstractEntity.escapeString( db.getSystemEncoding() );
		aJDBCP = createMySqlAdminProcessor();
		aJDBCP.addSQL( "CREATE DATABASE " + aName + " " + 
				"DEFAULT CHARACTER SET '" + aEncoding + "'");
		aJDBCP.addSQL( "GRANT ALL ON " + aName + ".* TO '" + aOwner + "'@'%' WITH GRANT OPTION" );
		return aJDBCP;
	}

	/// @return a Processor which updates a preexisting database
	public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity)
	{
		Database db = (Database) entity;
		assert db.getInstance().equals("mysql");
		
		String aName = AbstractEntity.escapeString( db.getName() );
		String aOwner = AbstractEntity.escapeString( db.getOwner() );
		String aEncoding = AbstractEntity.escapeString( db.getSystemEncoding() );
		JDBCProcessor aJDBCP = null;
		aJDBCP = createMySqlAdminProcessor();
		aJDBCP.addSQL( "ALTER DATABASE " + aName + " DEFAULT CHARACTER SET '" + aEncoding + "'" );
		aJDBCP.addSQL( "GRANT ALL ON " + aName + ".* TO '" + aOwner + "'@'%'" );
		// TODO: alte Admin-Rechte entziehen
		return aJDBCP;
	}

	/// @return a Processor which deletes an existing database
	public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity)
	{
		Database db = (Database) entity;
		assert db.getInstance().equals("mysql");

		JDBCProcessor aJDBCP = createMySqlAdminProcessor();
		String aName = AbstractEntity.escapeString( db.getName() );
		String aOwner = AbstractEntity.escapeString( db.getOwner() );
		aJDBCP.addSQL( "REVOKE ALL ON " + aName + ".* FROM '" + aOwner + "'@'%'" );
		aJDBCP.addSQL( "DROP DATABASE " + aName );
		return aJDBCP;
	}
}
