package com.k_int.npdb.datamodel;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.k_int.aggregator.util.SOLRHelper;
import com.k_int.aggregator.util.SOLRHelper.NVPair;

/**
 * Class Venue
 */
@Entity
@Table(name = "VENUE")
public class Venue {

	private Long id;
	private String externalId;
	private Source source;
	private String name;
	private String url;
	private Address address;
	private String type;
	private List<Venue> associatedVenues = new ArrayList<Venue>();
	private List<Performance> performances = new ArrayList<Performance>();
	private String description;

	public Venue() {
	};

	/**
	 * Get the value of id
	 * 
	 * @return the value of id
	 */
	@Id
	@Column(name = "ID")
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	/**
	 * Get the value of externalId
	 * 
	 * @return the value of externalId
	 */
	@Column(name = "EXTERNAL_ID")
	public String getExternalId() {
		return externalId;
	}

	/**
	 * Get the value of source
	 * 
	 * @return the value of source
	 */
	@ManyToOne
	@JoinColumn(name = "SOURCE_FK")
	public Source getSource() {
		return source;
	}

	/**
	 * Get the value of name
	 * 
	 * @return the value of name
	 */
	@Column(name = "NAME")
	public String getName() {
		return name;
	}

	/**
	 * Get the value of url
	 * 
	 * @return the value of url
	 */
	@Column(name = "URL")
	public String getUrl() {
		return url;
	}

	/**
	 * Get the value of address
	 * 
	 * @return the value of address
	 */
	@OneToOne
	@JoinColumn(name = "ADDRESS_FK")
	public Address getAddress() {
		return address;
	}

	/**
	 * Get the value of type
	 * 
	 * @return the value of type
	 */
	@Column(name = "TYPE")
	public String getType() {
		return type;
	}

	/**
	 * Get the value of associatedVenues
	 * 
	 * @return the value of associatedVenues
	 */
	@ManyToMany
	@JoinTable(name = "RELATED_VENUES", joinColumns = { @JoinColumn(name = "VENUE_FK") }, inverseJoinColumns = @JoinColumn(name = "RELATED_FK"))
	public List<Venue> getAssociatedVenues() {
		return associatedVenues;
	}

	/**
	 * Get the value of description
	 * 
	 * @return the value of description
	 */
	@Column(name = "DESCRIPTION")
	@Lob
	public String getDescription() {
		return description;
	}

	@OneToMany(mappedBy = "venue")
	public List<Performance> getPerformances() {
		return performances;
	}

	public void setPerformances(List<Performance> performances) {
		this.performances = performances;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public void setAssociatedVenues(List<Venue> associatedVenues) {
		this.associatedVenues = associatedVenues;
	}

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

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

	public void setExternalId(String externalId) {
		this.externalId = externalId;
	}

	public void setSource(Source source) {
		this.source = source;
	}

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

	public void setType(String type) {
		this.type = type;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public List<NVPair> toSOLRIndex() {
		List<NVPair> indexProperties = new ArrayList<NVPair>();
		indexProperties.add(new SOLRHelper.NVPair("internalId", "" + id));
		indexProperties.add(new SOLRHelper.NVPair("source", source.getName()));
		indexProperties.add(new SOLRHelper.NVPair("identifier", "venue_" + id));
		indexProperties.add(new SOLRHelper.NVPair("name", name));
		if (address != null)
			indexProperties.add(new SOLRHelper.NVPair("location", address
					.getTown()));
		indexProperties.add(new SOLRHelper.NVPair("type", "venue"));
		return indexProperties;
	}

	public static Venue lookupOrCreate(org.hibernate.Session session,
			Source source, String externalId, String name)
			throws org.hibernate.HibernateException {
		Venue result = null;
		org.hibernate.Query q = session
				.createQuery("select x from com.k_int.npdb.datamodel.Venue x where x.externalId = ? and x.source.name = ?");
		q.setString(0, externalId);
		q.setString(1, source.getName());
		result = (Venue) q.uniqueResult();
		/* No deduplication, cause there are several theatres with the same name (Civic Hall for Theatre Web)
		if (result == null && name != null) {
			q = session
					.createQuery("select x from com.k_int.npdb.datamodel.Venue x where x.name = ?");
			q.setString(0, name);
			List list = q.list();
			if (list.size() == 1)
				result = (Venue) list.get(0);
		}
		*/
		if (result == null) {
			result = new Venue();
			result.setExternalId(externalId);
			result.setSource(source);
			result.setName(name);
			session.save(result);
		}
		return result;
	}

}
