package org.wallride.core.domain;

import org.apache.commons.collections.CollectionUtils;
import org.hibernate.annotations.*;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.FieldBridge;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.joda.time.LocalDateTime;

import javax.persistence.CascadeType;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

@Entity
@Table(name = "post", uniqueConstraints = @UniqueConstraint(columnNames = {"code", "language"}))
@Inheritance(strategy = InheritanceType.JOINED)
@DynamicInsert
@DynamicUpdate
@Indexed
public class Post extends DomainObject<Long> {

	public enum Status {
		DRAFT, SCHEDULED, PUBLISHED
	}

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private long id;

	@Column(length=200)
	@Field
	private String code;

	@Column(length=3, nullable=false)
	@Field
	private String language;

	@Column(length=200)
	@Field
	private String title;

	@ManyToOne
	private Media cover;

	@Lob
	@Field
	private String body;

	@Embedded
	@IndexedEmbedded
	private Seo seo = new Seo();

	@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
	@Field
	@FieldBridge(impl=LocalDateTimeBridge.class)
	private LocalDateTime date;

	@ManyToOne
	@IndexedEmbedded
	private User author;

	@Enumerated(EnumType.STRING)
	@Column(length=50, nullable=false)
	@Field
	private Status status;

	@Column(nullable = false)
	private long views;

	@ManyToOne
	@IndexedEmbedded(depth = 1, indexNullAs = Field.DEFAULT_NULL_TOKEN)
	private Post drafted;

	@Column(name = "drafted_code", length = 200)
	private String draftedCode;

	@OneToMany(mappedBy = "drafted", cascade = CascadeType.ALL)
	@LazyCollection(LazyCollectionOption.EXTRA)
	@SortNatural
	private SortedSet<Post> drafts;

	@ManyToMany
	@JoinTable(
			name="post_related_post",
			joinColumns = { @JoinColumn(name="post_id")},
			inverseJoinColumns = { @JoinColumn(name="related_id") })
	private Set<Post> relatedToPosts = new HashSet<>();

	@ManyToMany
	@JoinTable(
			name="post_related_post",
			joinColumns = { @JoinColumn(name="related_id")},
			inverseJoinColumns = { @JoinColumn(name="post_id") })
	private Set<Post> relatedByPosts = new HashSet<>();

	@ManyToMany
	@JoinTable(name="post_media", joinColumns=@JoinColumn(name="post_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="media_id", referencedColumnName="id"))
	@OrderColumn(name="`index`")
	private List<Media> medias;

	@Override
	public Long getId() {
		return id;
	}

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

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Media getCover() {
		return cover;
	}

	public void setCover(Media cover) {
		this.cover = cover;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}

	public Seo getSeo() {
		return seo;
	}

	public void setSeo(Seo seo) {
		this.seo = seo;
	}

	public LocalDateTime getDate() {
		return date;
	}

	public void setDate(LocalDateTime date) {
		this.date = date;
	}

	public User getAuthor() {
		return author;
	}

	public void setAuthor(User author) {
		this.author = author;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public long getViews() {
		return views;
	}

	public void setViews(long views) {
		this.views = views;
	}

	public Post getDrafted() {
		return drafted;
	}

	public void setDrafted(Post drafted) {
		this.drafted = drafted;
	}

	public String getDraftedCode() {
		return draftedCode;
	}

	public void setDraftedCode(String draftedCode) {
		this.draftedCode = draftedCode;
	}

	public SortedSet<Post> getDrafts() {
		return drafts;
	}

	public void setDrafts(SortedSet<Post> drafts) {
		this.drafts = drafts;
	}

	public List<Media> getMedias() {
		return medias;
	}

	public List<Post> getRelatedPosts() {
		return (List<Post>)CollectionUtils.union(getRelatedToPosts(), getRelatedByPosts());
	}

	public Set<Post> getRelatedToPosts() {
		return relatedToPosts;
	}

	public void setRelatedToPosts(Set<Post> relatedToPosts) {
		this.relatedToPosts = relatedToPosts;
	}

	public Set<Post> getRelatedByPosts() {
		return relatedByPosts;
	}

	public void setRelatedByPosts(Set<Post> relatedByPosts) {
		this.relatedByPosts = relatedByPosts;
	}

	public void setMedias(List<Media> medias) {
		this.medias = medias;
	}

	@Override
	public String toString() {
		return getTitle();
	}
}

@@ -514,88 +514,9 @@
 til.
-HashSet;%0Aimport java.util.List;%0Aimport java.util.Set;%0Aimport java.util.SortedSet
+*
 ;%0A%0A@
@@ -4258,19 +4258,18 @@
 %09public 
-Lis
+Se
 t%3CPost%3E 
@@ -4290,22 +4290,44 @@
 s() %7B%0A%09%09
-return
+List%3CPost%3E relatedPostList =
  (List%3CP
@@ -4396,16 +4396,61 @@
 sts());%0A
+%09%09return new HashSet%3CPost%3E(relatedPostList);%0A
 %09%7D%0A%0A%09pub

Delete post with relation of relatedPosts