package com.faforever.api.data.domain;


import com.faforever.api.data.checks.UserGroupPublicCheck;
import com.faforever.api.security.elide.permission.WriteUserGroupCheck;
import com.yahoo.elide.annotation.CreatePermission;
import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import com.yahoo.elide.annotation.UpdatePermission;
import lombok.Setter;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Set;

@Entity
@Table(name = "user_group")
@Include(type = "userGroup")
@UpdatePermission(expression = WriteUserGroupCheck.EXPRESSION)
@CreatePermission(expression = WriteUserGroupCheck.EXPRESSION)
@ReadPermission(expression = UserGroupPublicCheck.EXPRESSION + " or " + WriteUserGroupCheck.EXPRESSION)
@Setter
public class UserGroup extends AbstractEntity {

  private String technicalName;
  private String nameKey;
  private boolean public_;
  private Set<User> members;
  private Set<GroupPermission> permissions;

  @Column(name = "technical_name")
  public String getTechnicalName() {
    return technicalName;
  }

  @Column(name = "name_key")
  public String getNameKey() {
    return nameKey;
  }

  @Column(name = "public")
  public boolean isPublic() {
    return public_;
  }

  public void setPublic(boolean public_) {
    this.public_ = public_;
  }

  @JoinTable(name = "user_group_assignment",
    joinColumns = @JoinColumn(name = "group_id"),
    inverseJoinColumns = @JoinColumn(name = "user_id")
  )
  @ManyToMany(cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE
  })
  public @NotNull
  @Valid Set<User> getMembers() {
    return members;
  }

  @JoinTable(name = "group_permission_assignment",
    joinColumns = @JoinColumn(name = "group_id"),
    inverseJoinColumns = @JoinColumn(name = "permission_id")
  )
  @ManyToMany(cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE
  })
  public @NotNull
  @Valid Set<GroupPermission> getPermissions() {
    return permissions;
  }
}

@@ -599,16 +599,88 @@
 ToMany;%0A
+import javax.persistence.ManyToOne;%0Aimport javax.persistence.OneToMany;%0A
 import j
@@ -699,24 +699,24 @@
 ence.Table;%0A
-
 import javax
@@ -865,16 +865,34 @@
 erGroup%22
+, rootLevel = true
 )%0A@Updat
@@ -1135,17 +1135,17 @@
 ic class
- 
+%0A
 UserGrou
@@ -1257,16 +1257,79 @@
 ublic_;%0A
+  private UserGroup parent;%0A  private Set%3CUserGroup%3E children;%0A
   privat
@@ -1635,24 +1635,24 @@
 sPublic() %7B%0A
-
     return p
@@ -1664,16 +1664,226 @@
 _;%0A  %7D%0A%0A
+  @ManyToOne%0A  @JoinColumn(name = %22parent_group_id%22)%0A  public UserGroup getParent() %7B%0A    return parent;%0A  %7D%0A%0A  @OneToMany(mappedBy = %22parent%22)%0A  public Set%3CUserGroup%3E getChildren() %7B%0A    return children;%0A  %7D%0A%0A
   public

Add UserGroup to root level and show parent/children