/**
   * @param projectIdentifier
   * @param description
   * @param projectManager
   * @param plannedTime
   * @return Project
   * @throws WaktuException
   */
  public Project addProject(
      final String projectIdentifier,
      final String description,
      final Usr projectManager,
      final int plannedTime)
      throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    Project newProject = new Project(projectIdentifier, description, projectManager, plannedTime);

    BusinessRuleController.check(newProject);

    try {
      em.getTransaction().begin();
      em.persist(newProject);
      em.getTransaction().commit();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    add.emit(newProject);
    logger.info("project " + newProject + " added");
    return newProject;
  }
  /**
   * @param projectId
   * @return Project
   * @throws WaktuException
   */
  public Project getProject(final int projectId) throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    Project project = null;
    try {
      project = em.find(Project.class, projectId);
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }
    return project;
  }
  /**
   * @return List<Usr>
   * @throws WaktuException
   */
  @SuppressWarnings("unchecked")
  public List<Usr> getAllUsers() throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    List<Usr> allUsers = null;

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    try {
      allUsers = em.createQuery("SELECT u FROM Usr u ORDER BY u.firstname").getResultList();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    return allUsers;
  }
  /**
   * @param username
   * @return Usr
   * @throws WaktuException
   */
  public Usr getUser(final String username) throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    Usr usr = null;

    try {
      usr =
          (Usr)
              em.createQuery("SELECT u FROM Usr u WHERE u.username = '******'")
                  .getSingleResult();
    } catch (NoResultException e) {
      throw new WaktuException("User or password wrong!");
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    return usr;
  }
  /**
   * @param usr
   * @throws WaktuException
   */
  public void updateUser(final Usr usr) throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    BusinessRuleController.check(usr);

    try {
      em.getTransaction().begin();
      em.merge(usr);
      em.getTransaction().commit();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }
    update.emit();
    logger.info("user " + usr + " updated");
  }
  /**
   * @return List<Project>
   * @throws WaktuException
   */
  @SuppressWarnings("unchecked")
  public List<Project> getAllProjects() throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    List<Project> allProjects = null;
    try {
      allProjects =
          em.createQuery("SELECT p FROM Project p ORDER BY p.projectIdentifier ASC")
              .getResultList();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    return allProjects;
  }
  /**
   * @param firstname
   * @param lastname
   * @param password
   * @param pensum
   * @param role
   * @param holiday
   * @return Usr
   * @throws WaktuException
   */
  public Usr addUser(
      final String firstname,
      final String lastname,
      final String password,
      final int pensum,
      final SystemRole role,
      final double holiday)
      throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    Usr newUsr =
        new Usr(
            generateUsername(firstname, lastname),
            firstname,
            lastname,
            Md5.hash(password),
            pensum,
            role,
            holiday);

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    BusinessRuleController.check(newUsr);

    try {
      em.getTransaction().begin();
      em.persist(newUsr);
      em.getTransaction().commit();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    add.emit(newUsr);
    logger.info("user " + newUsr + " added");
    return newUsr;
  }
  /**
   * @return List<Usr>
   * @throws WaktuException
   */
  @SuppressWarnings("unchecked")
  public List<Usr> getProjectManagers() throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    List<Usr> allProjectManagers = null;

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    try {
      allProjectManagers =
          em.createQuery(
                  "SELECT u FROM Usr u JOIN u.systemRole s WHERE u.systemRole = ch.hsr.waktu.domain.SystemRole.PROJECTMANAGER OR u.systemRole = ch.hsr.waktu.domain.SystemRole.ADMIN ORDER BY u.firstname")
              .getResultList();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    return allProjectManagers;
  }
  /**
   * @param usr
   * @return List<Project>
   * @throws WaktuException
   */
  @SuppressWarnings("unchecked")
  public List<Project> getActiveProjects(final Usr usr) throws WaktuException {
    EntityManager em = PersistenceController.getInstance().getEMF().createEntityManager();

    if (!PermissionController.getInstance().checkPermission()) {
      throw new WaktuException("Permission denied");
    }

    List<Project> activeProjectsOfUser = null;
    try {
      activeProjectsOfUser =
          em.createQuery(
                  "SELECT p FROM ProjectStaff ps JOIN ps.project p JOIN ps.user u WHERE u.id = '"
                      + usr.getId()
                      + "' ORDER BY p.projectIdentifier ASC")
              .getResultList();
    } catch (Exception e) {
      ExceptionHandling.handleException(e);
    } finally {
      em.close();
    }

    return activeProjectsOfUser;
  }