package info.bukova.isspst.services.users;

import info.bukova.isspst.data.Permission;
import info.bukova.isspst.data.Role;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractService;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.springframework.transaction.annotation.Transactional;

public class RoleServiceImpl extends AbstractService<Role> implements RoleService {

	@Override
	@Transactional
	public Role getRoleByAuthority(String authority) {
		return this.selectSingle("from Role where authority = '" + authority + "'");
	}

	@Override
	@Transactional
	public List<Role> getWorkgroupRoles() {
		return this.execQuery("from Role where workgroup = true");
	}

	@Override
	@Transactional
	public List<Role> getCentreRoles() {
		return this.execQuery("from Role where centre = true");
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public List<Role> getRolesWithPermission(Permission perm, String moduleId, boolean centre) {
		String wgClausule;
		if (centre) {
			wgClausule = "centre";
		} else {
			wgClausule = "workgroup";
		}
		Set<Permission> perms = new HashSet<Permission>();
		perms.add(perm);
		Query q = dao.getQuery("select r from Role r join r.permissions p where r." + wgClausule + " = true and p.module = :module and p in (:perms)");
		q.setParameterList("perms", perms);
		q.setParameter("module", moduleId);
		return q.list();
	}

	@Override
	@Transactional
	public List<Role> getRolesWithPermission(String authority, String moduleId, boolean centre) {
		Query q = dao.getQuery("from Permission where authority = '" + authority + "' and module = '" + moduleId + "'");
		Permission p = (Permission) q.uniqueResult(); 
		return getRolesWithPermission(p, moduleId, centre);
	}

	@Override
	@Transactional
	public boolean canChangeWorkgroup(Role role) {
		Query q = dao.getQuery("select count(w) from Workgroup w join w.members m where w.centre = false and m.role = :role");
		q.setParameter("role", role);
		long i = (Long)q.uniqueResult();
		return i == 0;
	}

	@Override
	@Transactional
	public boolean canChangeCenter(Role role) {
		Query q = dao.getQuery("select count(w) from Workgroup w join w.members m where w.centre = true and m.role = :role");
		q.setParameter("role", role);
		long i = (Long)q.uniqueResult();
		return i == 0;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public List<Workgroup> getRoleUsage(Role role) {
		Query q = dao.getQuery("select distinct w from Workgroup w join w.members m where m.role = :role");
		q.setParameter("role", role);
		return q.list();
	}

	@Override
	@Transactional
	public boolean isInWorkflow(Role role) {
		Query q = dao.getQuery("select count(rt) from RequirementType rt join rt.workflow w join w.role role where role = :role");
		q.setParameter("role", role);
		long i = (Long)q.uniqueResult();
		return i != 0;
	}

}
