package de.hsadmin.mods.user;

import javax.persistence.EntityManager;

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

/**
 * Factory class which creates Processor instances for dealing with UNIX user
 * accounts.
 * 
 * @author mi
 */
public class UnixUserProcessorFactory implements EntityProcessorFactory {
	
	/** 
	 * @return a Processor which creates a new UNIX user account
	 */
	public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em,
			T entity) {
		UnixUser user = (UnixUser) entity;
		CompoundProcessor aCP = new CompoundProcessor(new ShellProcessor(
				"newusers", user.getName() + ":" + user.getPassword() + ":"
						+ user.getUserId() + ":" + user.getPac().getName()
						+ ":" + user.getComment() + ":" + user.getHomedir()
						+ ":" + user.getShell() + "\n"));
		appendSetQuotaProcessor(aCP, user);
		appendMakeMaildirProcessor(aCP, user);
		return aCP;
	}

	/**
	 *  @return a Processor which updates an existing UNIX user account
	 */
	public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em,
			T entity) {
		UnixUser user = (UnixUser) entity;
		CompoundProcessor aCP = new CompoundProcessor(new ShellProcessor(
				"usermod -c '" + user.getComment() + "'" + " -d '"
						+ user.getHomedir() + "'" + " -s '" + user.getShell()
						+ "' " + user.getName()));
		if (user.getPassword() != null && user.getPassword().length() > 0)
			aCP.appendProcessor(new ShellProcessor("chpasswd ", user.getName()
					+ ":" + user.getPassword() + "\n"));
		appendSetQuotaProcessor(aCP, user);
		return aCP;
	}

	/**
	 *  @return a Processor which deletes an existing UNIX user account
	 */
	public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity) {
		UnixUser user = (UnixUser) entity;
		String uid = user.getName();
		if (uid != null && uid.length() > 4) {
			Processor userdelProc = null;
			if (user.isDefaultHomedir()) {
				userdelProc = new ShellProcessor("userdel " + uid + " && rm -rf '" + user.getHomedir() + "'");
			} else {
				userdelProc = new ShellProcessor("userdel " + uid);
			}
			CompoundProcessor proc = new CompoundProcessor(userdelProc);
			proc.appendProcessor(new ShellProcessor("rm -f '/var/spool/cron/crontabs/" + uid + "'"));
			proc.appendProcessor(new ShellProcessor("rm -f '/var/mail/" + uid + "'"));
			return proc;
		}
		return null;
	}

	private void appendSetQuotaProcessor(CompoundProcessor aCP, UnixUser user) {
		Integer quotaSoft = user.getQuotaSoftlimit();
		if (quotaSoft == null || quotaSoft.intValue() == 0) {
			aCP.appendProcessor(new ShellProcessor("setquota -u "
					+ user.getName() + " 0 0 0 0 "
					+ "`df /home/pacs/ | tail -n1 | cut -d' ' -f1`"));
			return;
		}
		Integer userSoftQuota = quotaSoft * 1024;
		Integer quotaHard = user.getQuotaHardlimit();
		if (quotaHard == null) {
			quotaHard = new Integer(0);
		}
		Integer userHardQuota = quotaHard * 1024;
		if (userHardQuota.intValue() < userSoftQuota.intValue()) {
			// set default value 
			userHardQuota = ((Double) (userSoftQuota * 1.5 + 32)).intValue();
		}
		aCP.appendProcessor(new ShellProcessor("setquota -u "
				+ user.getName() + " " + userSoftQuota + " "
				+ userHardQuota + " 0 0 "
				+ "`df /home/pacs/ | tail -n1 | cut -d' ' -f1`"));
	}

	private void appendMakeMaildirProcessor(CompoundProcessor aCP, UnixUser user) {
		aCP.appendProcessor(
				new ShellProcessor(
						"su -l " + user.getName() + " -s \"/bin/bash\" -c \"maildirmake " +
						user.getHomedir() + "/Maildir" +
						"\""
				));
	}

}
