package com.bloatit.model.data;

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

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NamedQuery;

import com.bloatit.common.PageIterable;
import com.bloatit.model.data.util.SessionManager;

// DaoGroup is SQL keyword
@Entity
@NamedQuery(name = "getMembers", query = "select m from com.bloatit.model.data.DaoGroup g join g.groupMembership as gm join gm.member as m where g = :group")
public class DaoGroup extends DaoActor {

    public enum Right {
        PUBLIC, PROTECTED;
    }

    // right is a SQL keyword.
    @Basic(optional = false)
    @Column(name = "group_right")
    private Right right;

    @OneToMany(mappedBy = "group")
    @Cascade(value = { CascadeType.ALL, CascadeType.DELETE_ORPHAN })
    private Set<DaoGroupMembership> groupMembership = new HashSet<DaoGroupMembership>(0);

    protected DaoGroup() {
        super();
    }

    /**
     * Create a group and add it into the db.
     * 
     * @param name
     *            it the unique and non updatable name of the group.
     * @param owner
     *            is the DaoMember creating this group.
     * @param right
     *            is the type of group we are creating.
     * @return the newly created group.
     * @throws HibernateException
     */
    static public DaoGroup createAndPersiste(String login, String email, Right right) throws HibernateException {
        final Session session = SessionManager.getSessionFactory().getCurrentSession();
        final DaoGroup Group = new DaoGroup(login, email, right);
        try {
            session.save(Group);
        } catch (final HibernateException e) {
            session.getTransaction().rollback();
            throw e;
        }
        return Group;
    }

    /**
     * Find a DaoGroup using its login.
     * 
     * @param name
     *            the member login.
     * @return null if not found.
     */
    public static DaoGroup getByName(String name) {
        final Session session = SessionManager.getSessionFactory().getCurrentSession();
        final Query q = session.createQuery("from com.bloatit.model.data.DaoGroup where login = :login");
        q.setString("login", name);
        return (DaoGroup) q.uniqueResult();
    }

    public DaoGroup(String login, String email, Right right) {
        super(login, email);
        this.right = right;
    }

    public PageIterable<DaoMember> getMembers() {
        final Session session = SessionManager.getSessionFactory().getCurrentSession();
        final Query q = session.getNamedQuery("getMembers");
        q.setParameter("group", this);
        return new QueryCollection<DaoMember>(q);
    }

    public void addMember(DaoMember Member, boolean isAdmin) {
        groupMembership.add(new DaoGroupMembership(Member, this, isAdmin));
    }

    public void removeMember(DaoMember Member) {
        final DaoGroupMembership link = DaoGroupMembership.get(this, Member);
        groupMembership.remove(link);
        Member.getGroupMembership().remove(link);
    }

    public Right getRight() {
        return right;
    }

    public void setRight(Right right) {
        this.right = right;
    }

    // ======================================================================
    // For hibernate mapping
    // ======================================================================

    protected void setGroupMembership(Set<DaoGroupMembership> GroupMembership) {
        this.groupMembership = GroupMembership;
    }

    protected Set<DaoGroupMembership> getGroupMembership() {
        return groupMembership;
    }

}

@@ -824,24 +824,95 @@
 TED;%0A    %7D%0A%0A
+    public enum MemberStatus %7B%0A        UNKNOWN, IN_GROUP, ADMIN%0A    %7D%0A%0A
     // right
@@ -930,16 +930,16 @@
 eyword.%0A
-
     @Bas
@@ -2129,155 +2129,34 @@
    /
-**%0A     * Find a DaoGroup using its login.%0A     * %0A     * @param name%0A     *            the member login.%0A     * @return null if not found.%0A     */
+/ TODO test me correctly !
 %0A   
@@ -3366,32 +3366,32 @@
 (Right right) %7B%0A
-
         this.rig
@@ -3405,24 +3405,715 @@
 ght;%0A    %7D%0A%0A
+    public MemberStatus getMemberStatus(DaoMember member) %7B%0A        Query q = SessionManager.getSessionFactory()%0A                                .getCurrentSession()%0A                                .createQuery(%22select gm from com.bloatit.model.data.DaoGroup g join g.groupMembership as gm join gm.member as m where g = :group and m = :member%22);%0A        q.setEntity(%22member%22, member);%0A        q.setEntity(%22group%22, this);%0A        DaoGroupMembership gm = (DaoGroupMembership) q.uniqueResult();%0A        if (gm == null) %7B%0A            return MemberStatus.UNKNOWN;%0A        %7D%0A        if (gm.isAdmin()) %7B%0A            return MemberStatus.ADMIN;%0A        %7D%0A        return MemberStatus.IN_GROUP;%0A    %7D%0A%0A
     // =====

add an easy way to now if a member is admin, in a group or not