package io.openex.database.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.openex.database.audit.ModelBaseListener;
import io.openex.helper.MonoModelDeserializer;
import io.openex.helper.MultiModelDeserializer;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "audiences")
@EntityListeners(ModelBaseListener.class)
public class Audience implements Base {
    @Id
    @Column(name = "audience_id")
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @JsonProperty("audience_id")
    private String id;

    @Column(name = "audience_name")
    @JsonProperty("audience_name")
    private String name;

    @Column(name = "audience_description")
    @JsonProperty("audience_description")
    private String description;

    @Column(name = "audience_enabled")
    @JsonProperty("audience_enabled")
    private boolean enabled = true;

    @ManyToOne
    @JoinColumn(name = "audience_exercise")
    @JsonSerialize(using = MonoModelDeserializer.class)
    @JsonProperty("audience_exercise")
    private Exercise exercise;

    @Column(name = "audience_created_at")
    @JsonProperty("audience_created_at")
    private Date createdAt = new Date();

    @Column(name = "audience_updated_at")
    @JsonProperty("audience_updated_at")
    private Date updatedAt = new Date();
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "audiences_tags",
            joinColumns = @JoinColumn(name = "audience_id"),
            inverseJoinColumns = @JoinColumn(name = "tag_id"))
    @JsonSerialize(using = MultiModelDeserializer.class)
    @JsonProperty("audience_tags")
    @Fetch(FetchMode.SUBSELECT)
    private List<Tag> tags = new ArrayList<>();

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "users_audiences",
            joinColumns = @JoinColumn(name = "audience_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id"))
    @JsonSerialize(using = MultiModelDeserializer.class)
    @JsonProperty("audience_users")
    @Fetch(FetchMode.SUBSELECT)
    private List<User> users = new ArrayList<>();

    @JsonProperty("audience_users_number")
    public long getUsersNumber() {
        return getUsers().size();
    }

    @JsonIgnore
    @Override
    public boolean isUserObserver(User user) {
        return getExercise().isUserObserver(user);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public Date getCreatedAt() { return createdAt; }

    public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; }

    public Date getUpdatedAt() { return updatedAt; }

    public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public Exercise getExercise() {
        return exercise;
    }

    public void setExercise(Exercise exercise) {
        this.exercise = exercise;
    }
}

@@ -2460,103 +2460,624 @@
    @
-JsonProperty(%22audience_users_number%22)%0A    public long getUsersNumber() %7B%0A        return getUser
+ManyToMany(fetch = FetchType.EAGER)%0A    @JoinTable(name = %22injects_audiences%22,%0A            joinColumns = @JoinColumn(name = %22audience_id%22),%0A            inverseJoinColumns = @JoinColumn(name = %22inject_id%22))%0A    @JsonSerialize(using = MultiModelDeserializer.class)%0A    @JsonProperty(%22audience_injects%22)%0A    @Fetch(FetchMode.SUBSELECT)%0A    private List%3CInject%3C?%3E%3E injects = new ArrayList%3C%3E();%0A%0A    @JsonProperty(%22audience_users_number%22)%0A    public long getUsersNumber() %7B%0A        return getUsers().size();%0A    %7D%0A%0A    @JsonProperty(%22audience_injects_number%22)%0A    public long getInjectsNumber() %7B%0A        return getInject
 s().
@@ -4331,32 +4331,198 @@
 = users;%0A    %7D%0A%0A
+    public List%3CInject%3C?%3E%3E getInjects() %7B%0A        return injects;%0A    %7D%0A%0A    public void setInjects(List%3CInject%3C?%3E%3E injects) %7B%0A        this.injects = injects;%0A    %7D%0A%0A
     public Exerc

Add injects listing and number in Audience model