package de.hsadmin.mods.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.model.Transaction;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;

public class PgSqlDatabaseModuleImpl extends AbstractModuleImpl {

	@Override
	public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
		if (orderBy == null || orderBy.length() == 0) {
			orderBy = "ORDER BY obj.name ASC";
		}
		return super.search(entityClass, condition, orderBy);
	}

	@Override
	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
		UnixUser loginUser = getTransaction().getLoginUser();
		PgSqlDatabase database = (PgSqlDatabase) newEntity;
		String name = database.getName();
		String pacPrefix = name.substring(0, 5);
		if (name.length() < 7 || name.charAt(5) != '_') {
			throw new AuthorisationException(loginUser, "add", newEntity);
		}
		String owner = database.getOwner();
		if (owner == null || name.length() < 7 || name.charAt(5) != '_') {
			if (name.length() != 5) {
				throw new HSAdminException("database owner required");
			}
		}
		if (!owner.startsWith(pacPrefix)) {
			throw new HSAdminException("wrong database owner");
		}
		EntityManager em = getTransaction().getEntityManager();
		Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
		qPac.setParameter("pacName", name.substring(0, 5));
		Object singleResult = qPac.getSingleResult();
		Pac pac = (Pac) singleResult;
		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
			throw new AuthorisationException(loginUser, "add", newEntity);
		}
		if (!pac.getName().equals(pacPrefix)) {
			throw new HSAdminException("wrong database owner");
		}
		database.setPac(pac);
		return super.add(newEntity);
	}
	
	@Override
	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
		Transaction transaction = getTransaction();
		EntityManager em = transaction.getEntityManager();
		UnixUser unixUser = transaction.getLoginUser();
		MySqlDatabase detachtedDB = (MySqlDatabase) existingEntity;
		MySqlDatabase attachedDB = em.find(MySqlDatabase.class, detachtedDB.getId());
		if (!attachedDB.getName().equals(detachtedDB.getName())) {
			throw new AuthorisationException(unixUser, "update", existingEntity, "name");
		}
		if (!attachedDB.getEncoding().equals(detachtedDB.getEncoding())) {
			throw new AuthorisationException(unixUser, "update", existingEntity, "encoding");
		}
		if (!attachedDB.getInstance().equals(detachtedDB.getInstance())) {
			throw new AuthorisationException(unixUser, "update", existingEntity, "instance");
		}
		return super.update(existingEntity);
	}

}
