/**
 * 
 */
package de.bstly.board.model;

import java.time.Instant;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.search.engine.backend.types.Projectable;
import org.hibernate.search.engine.backend.types.Searchable;
import org.hibernate.search.engine.backend.types.Sortable;
import org.hibernate.search.mapper.pojo.bridge.mapping.annotation.ValueBridgeRef;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import com.google.common.collect.Maps;

import de.bstly.board.model.support.FlaggedStatus;
import de.bstly.board.model.support.InstantValueBridge;
import de.bstly.board.model.support.Types;

/**
 * The Class Comment.
 */
@Entity
@Table(name = "comments")
@EntityListeners({ AuditingEntityListener.class })
@Indexed
public class Comment {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false)
	private Long id;
	@Column(name = "author", nullable = false)
	private String author;
	@Column(name = "created", nullable = false)
	@KeywordField(name = "created", valueBridge = @ValueBridgeRef(type = InstantValueBridge.class), projectable = Projectable.YES, sortable = Sortable.YES)
	private Instant created;
	@Column(name = "target", nullable = false)
	private Long target;
	@Column(name = "parent", nullable = true)
	private Long parent;
	@Lob
	@Column(name = "text", nullable = false)
	@FullTextField(name = "text", searchable = Searchable.YES, analyzer = "english")
	@FullTextField(name = "text_de", searchable = Searchable.YES, analyzer = "german")
	private String text;
	@Enumerated(EnumType.STRING)
	@Column(name = "flagged_status", nullable = false, columnDefinition = "varchar(255) default 'NORMAL'")
	private FlaggedStatus flaggedStatus;
	@Transient
	private Map<String, Object> metadata;
	@Transient
	private final Types type = Types.comment;

	/**
	 * Gets the id.
	 *
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * Sets the id.
	 *
	 * @param id the new id
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Gets the author.
	 *
	 * @return the author
	 */
	public String getAuthor() {
		return author;
	}

	/**
	 * Sets the author.
	 *
	 * @param author the new author
	 */
	public void setAuthor(String author) {
		this.author = author;
	}

	/**
	 * Gets the created.
	 *
	 * @return the created
	 */
	public Instant getCreated() {
		return created;
	}

	/**
	 * Sets the created.
	 *
	 * @param created the new created
	 */
	public void setCreated(Instant created) {
		this.created = created;
	}

	/**
	 * Gets the target.
	 *
	 * @return the target
	 */
	public Long getTarget() {
		return target;
	}

	/**
	 * Sets the target.
	 *
	 * @param target the new target
	 */
	public void setTarget(Long target) {
		this.target = target;
	}

	/**
	 * Gets the parent.
	 *
	 * @return the parent
	 */
	public Long getParent() {
		return parent;
	}

	/**
	 * Sets the parent.
	 *
	 * @param parent the new parent
	 */
	public void setParent(Long parent) {
		this.parent = parent;
	}

	/**
	 * Gets the text.
	 *
	 * @return the text
	 */
	public String getText() {
		return text;
	}

	/**
	 * Sets the text.
	 *
	 * @param text the new text
	 */
	public void setText(String text) {
		this.text = text;
	}

	/**
	 * Gets the flagged status.
	 *
	 * @return the flagged status
	 */
	public FlaggedStatus getFlaggedStatus() {
		return flaggedStatus;
	}

	/**
	 * Sets the flagged status.
	 *
	 * @param flaggedStatus the new flagged status
	 */
	public void setFlaggedStatus(FlaggedStatus flaggedStatus) {
		this.flaggedStatus = flaggedStatus;
	}

	/**
	 * Gets the metadata.
	 *
	 * @return the metadata
	 */
	public Map<String, Object> getMetadata() {
		if (metadata == null) {
			metadata = Maps.newHashMap();
		}

		return metadata;
	}

	/**
	 * Sets the metadata.
	 *
	 * @param metadata the metadata
	 */
	public void setMetadata(Map<String, Object> metadata) {
		this.metadata = metadata;
	}

	/**
	 * @return the type
	 */
	public Types getType() {
		return type;
	}

}
