package edu.northwestern.bioinformatics.studycalendar.domain;


import gov.nih.nci.cabig.ctms.domain.AbstractMutableDomainObject;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;


@Entity
@Table(name = "user_roles")
@GenericGenerator(name="id-generator", strategy = "native",
    parameters = {
        @Parameter(name="sequence", value="seq_user_roles_id")
    }
)
public class UserRole  extends AbstractMutableDomainObject {
    private User user;
    private Role role;
    // TODO: why is one of these a set and the other a list?
    private Set<Site> sites = new HashSet<Site>();
    private List<StudySite> studySites = new ArrayList<StudySite>();

    public UserRole() { }

    public UserRole(User user, Role role) {
        this.user = user;
        this.role = role;
    }

    public UserRole(User user, Role role, Site... sites) {
        this.user = user;
        this.role = role;

        for (Site site: sites) {
            addSite(site);
        }
    }

    @ManyToOne
    @JoinColumn(name = "user_id")
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Type(type = "userRole")
    @Column(name="csm_group_name")
    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }


    @OneToMany
    @JoinTable( name="user_role_sites",
        joinColumns = @JoinColumn(name="user_role_id"),
        inverseJoinColumns = @JoinColumn(name="site_id")
    )
    public Set<Site> getSites() {
        return sites;
    }

    public void setSites(Set<Site> sites) {
        this.sites = sites;
    }

    public void addSite(Site site) {
        sites.add(site);
    }

    public void removeSite(Site site) {
        if (sites.contains(site)) {
            sites.remove(site);
        }
    }

    @ManyToMany
    @JoinTable( name="user_role_study_sites",
        joinColumns = @JoinColumn(name="user_role_id"),
        inverseJoinColumns = @JoinColumn(name="study_site_id")
    )
    public List<StudySite> getStudySites() {
        return studySites;
    }

    public void setStudySites(List<StudySite> studySites) {
        this.studySites = studySites;
    }

    public void addStudySite(StudySite studySite) {
        studySites.add(studySite);
    }

    public void clearStudySites() {
        studySites.clear();
    }

    public void removeStudySite(StudySite studySite) {
        studySites.remove(studySite);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserRole userRole = (UserRole) o;

        if (user != null ? !user.equals(userRole.user) : userRole.user != null) return false;
        if (role != null ? !role.equals(userRole.role) : userRole.role != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result;
        result = (user != null ? user.hashCode() : 0);
        result = 29 * result + (role != null ? role.hashCode() : 0);
        return result;
    }
}

@@ -56,17 +56,16 @@
 omain;%0A%0A
-%0A
 import g
@@ -286,57 +286,290 @@
 nce.
-*;%0Aimport java.util.HashSet;%0Aimport java.util.Set
+Column;%0Aimport javax.persistence.Entity;%0Aimport javax.persistence.JoinColumn;%0Aimport javax.persistence.JoinTable;%0Aimport javax.persistence.ManyToMany;%0Aimport javax.persistence.ManyToOne;%0Aimport javax.persistence.OneToMany;%0Aimport javax.persistence.Table;%0Aimport java.io.Serializable
 ;%0Aim
@@ -583,16 +583,21 @@
 va.util.
+Array
 List;%0Aim
@@ -611,27 +611,69 @@
 va.util.
-ArrayList;%0A
+HashSet;%0Aimport java.util.List;%0Aimport java.util.Set;
 %0A%0A@Entit
@@ -911,16 +911,40 @@
 nObject 
+implements Serializable 
 %7B%0A    pr

mark serializable