package eu.dnetlib.enabling.datasources.common;

import java.sql.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;

import com.google.common.collect.Sets;

/**
 * Datasource
 */
@MappedSuperclass
public abstract class Datasource<ORG extends Organization<?>, ID extends Identity, PIDSYSTEM extends PidSystem> {

	@Id
	protected String id;

	@Column(nullable = false)
	protected String officialname;
	protected String englishname;
	protected String websiteurl;
	protected String logourl;
	protected String contactemail;
	protected Double latitude;
	protected Double longitude;
	protected String timezone;
	protected String status;

	@Column(name = "namespaceprefix", columnDefinition = "bpchar(12)", nullable = false, updatable = false)
	protected String namespaceprefix;

	protected String languages;

	protected String collectedfrom;
	protected Date dateofvalidation;

	@Column(name = "eosc_datasource_type")
	protected String eoscDatasourceType;

	protected String provenanceaction;
	protected Date dateofcollection;
	protected String platform;

	@Column(name = "activationid")
	protected String activationId;
	protected String description;

	protected Date releasestartdate;
	protected Date releaseenddate;
	protected String missionstatementurl;

	protected String databaseaccesstype;
	protected String datauploadtype;
	protected String databaseaccessrestriction;
	protected String datauploadrestriction;

	protected String citationguidelineurl;

	@OneToMany(mappedBy = "id.service", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	protected Set<PIDSYSTEM> pidsystems = Sets.newHashSet();

	protected String certificates;
	protected String aggregator;

	protected String issn;
	protected String eissn;
	protected String lissn;

	protected String registeredby;

	private Date registrationdate;

	protected String subjects;

	protected Boolean managed;

	@Column(name = "consenttermsofuse")
	protected Boolean consentTermsOfUse;

	@Column(name = "consenttermsofusedate")
	protected Date consentTermsOfUseDate;

	@Column(name = "lastconsenttermsofusedate")
	protected Date lastConsentTermsOfUseDate;

	@Column(name = "fulltextdownload")
	protected Boolean fullTextDownload;

	@ManyToMany(cascade = {
		CascadeType.PERSIST, CascadeType.MERGE
	}, fetch = FetchType.LAZY)
	@JoinTable(name = "dsm_service_organization", joinColumns = @JoinColumn(name = "service"), inverseJoinColumns = @JoinColumn(name = "organization"))
	protected Set<ORG> organizations;

	@ManyToMany(cascade = {
		CascadeType.PERSIST, CascadeType.MERGE
	}, fetch = FetchType.LAZY)
	@JoinTable(name = "dsm_servicepids", joinColumns = @JoinColumn(name = "service"), inverseJoinColumns = @JoinColumn(name = "pid"))
	protected Set<ID> identities;

	@Column(name = "primary_provide_gateway")
	protected String primaryProvideGateway;

	public Datasource() {}

	public String getId() {
		return id;
	}

	public String getOfficialname() {
		return officialname;
	}

	public String getEnglishname() {
		return englishname;
	}

	public String getWebsiteurl() {
		return websiteurl;
	}

	public String getLogourl() {
		return logourl;
	}

	public String getContactemail() {
		return contactemail;
	}

	public Double getLatitude() {
		return latitude;
	}

	public Double getLongitude() {
		return longitude;
	}

	public String getTimezone() {
		return timezone;
	}

	public String getNamespaceprefix() {
		return namespaceprefix;
	}

	public String getLanguages() {
		return languages;
	}

	public String getCollectedfrom() {
		return collectedfrom;
	}

	public Date getDateofvalidation() {
		return dateofvalidation;
	}

	public String getProvenanceaction() {
		return provenanceaction;
	}

	public Date getDateofcollection() {
		return dateofcollection;
	}

	public String getPlatform() {
		return platform;
	}

	public String getActivationId() {
		return activationId;
	}

	public String getDescription() {
		return description;
	}

	public Date getReleasestartdate() {
		return releasestartdate;
	}

	public Date getReleaseenddate() {
		return releaseenddate;
	}

	public String getMissionstatementurl() {
		return missionstatementurl;
	}

	public String getDatabaseaccesstype() {
		return databaseaccesstype;
	}

	public String getDatauploadtype() {
		return datauploadtype;
	}

	public String getDatabaseaccessrestriction() {
		return databaseaccessrestriction;
	}

	public String getDatauploadrestriction() {
		return datauploadrestriction;
	}

	public String getCitationguidelineurl() {
		return citationguidelineurl;
	}

	public Set<PIDSYSTEM> getPidsystems() {
		return pidsystems;
	}

	public String getCertificates() {
		return certificates;
	}

	public String getAggregator() {
		return aggregator;
	}

	public String getIssn() {
		return issn;
	}

	public String getEissn() {
		return eissn;
	}

	public String getLissn() {
		return lissn;
	}

	public String getRegisteredby() {
		return registeredby;
	}

	public Date getRegistrationdate() {
		return registrationdate;
	}

	public String getSubjects() {
		return subjects;
	}

	public Boolean getManaged() {
		return managed;
	}

	public Boolean getConsentTermsOfUse() {
		return consentTermsOfUse;
	}

	public Date getConsentTermsOfUseDate() {
		return consentTermsOfUseDate;
	}

	public Boolean getFullTextDownload() {
		return fullTextDownload;
	}

	public Set<ORG> getOrganizations() {
		return organizations;
	}

	public Set<ID> getIdentities() {
		return identities;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setId(final String id) {
		this.id = id;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setOfficialname(final String officialname) {
		this.officialname = officialname;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setEnglishname(final String englishname) {
		this.englishname = englishname;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setWebsiteurl(final String websiteurl) {
		this.websiteurl = websiteurl;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLogourl(final String logourl) {
		this.logourl = logourl;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setContactemail(final String contactemail) {
		this.contactemail = contactemail;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLatitude(final Double latitude) {
		this.latitude = latitude;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLongitude(final Double longitude) {
		this.longitude = longitude;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setTimezone(final String timezone) {
		this.timezone = timezone;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setNamespaceprefix(final String namespaceprefix) {
		this.namespaceprefix = namespaceprefix;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLanguages(final String languages) {
		this.languages = languages;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setCollectedfrom(final String collectedfrom) {
		this.collectedfrom = collectedfrom;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDateofvalidation(final Date dateofvalidation) {
		this.dateofvalidation = dateofvalidation;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setProvenanceaction(final String provenanceaction) {
		this.provenanceaction = provenanceaction;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDateofcollection(final Date dateofcollection) {
		this.dateofcollection = dateofcollection;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setPlatform(final String platform) {
		this.platform = platform;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setActivationId(final String activationId) {
		this.activationId = activationId;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDescription(final String description) {
		this.description = description;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setReleasestartdate(final Date releasestartdate) {
		this.releasestartdate = releasestartdate;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setReleaseenddate(final Date releaseenddate) {
		this.releaseenddate = releaseenddate;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setMissionstatementurl(final String missionstatementurl) {
		this.missionstatementurl = missionstatementurl;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDatabaseaccesstype(final String databaseaccesstype) {
		this.databaseaccesstype = databaseaccesstype;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDatauploadtype(final String datauploadtype) {
		this.datauploadtype = datauploadtype;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDatabaseaccessrestriction(final String databaseaccessrestriction) {
		this.databaseaccessrestriction = databaseaccessrestriction;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setDatauploadrestriction(final String datauploadrestriction) {
		this.datauploadrestriction = datauploadrestriction;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setCitationguidelineurl(final String citationguidelineurl) {
		this.citationguidelineurl = citationguidelineurl;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setPidsystems(final Set<PIDSYSTEM> pidsystems) {
		this.pidsystems = pidsystems;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setCertificates(final String certificates) {
		this.certificates = certificates;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setAggregator(final String aggregator) {
		this.aggregator = aggregator;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setIssn(final String issn) {
		this.issn = issn;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setEissn(final String eissn) {
		this.eissn = eissn;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLissn(final String lissn) {
		this.lissn = lissn;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setRegisteredby(final String registeredby) {
		this.registeredby = registeredby;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setRegistrationdate(final Date registrationdate) {
		this.registrationdate = registrationdate;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setSubjects(final String subjects) {
		this.subjects = subjects;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setManaged(final Boolean managed) {
		this.managed = managed;
		return this;
	}

	public void setConsentTermsOfUse(final Boolean consentTermsOfUse) {
		this.consentTermsOfUse = consentTermsOfUse;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setConsentTermsOfUseDate(final Date consentTermsOfUseDate) {
		this.consentTermsOfUseDate = consentTermsOfUseDate;
		return this;
	}

	public void setFullTextDownload(final Boolean fullTextDownload) {
		this.fullTextDownload = fullTextDownload;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setOrganizations(final Set<ORG> organizations) {
		this.organizations = organizations;
		return this;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setIdentities(final Set<ID> identities) {
		this.identities = identities;
		return this;
	}

	public String getEoscDatasourceType() {
		return eoscDatasourceType;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setEoscDatasourceType(final String eoscDatasourceType) {
		this.eoscDatasourceType = eoscDatasourceType;
		return this;
	}

	public String getStatus() {
		return status;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setStatus(final String status) {
		this.status = status;
		return this;
	}

	public Date getLastConsentTermsOfUseDate() {
		return lastConsentTermsOfUseDate;
	}

	public Datasource<ORG, ID, PIDSYSTEM> setLastConsentTermsOfUseDate(final Date lastConsentTermsOfUseDate) {
		this.lastConsentTermsOfUseDate = lastConsentTermsOfUseDate;
		return this;
	}

	public String getPrimaryProvideGateway() {
		return primaryProvideGateway;
	}

	public void setPrimaryProvideGateway(final String primaryProvideGateway) {
		this.primaryProvideGateway = primaryProvideGateway;
	}

	public abstract String[] getAffiliatedProvideGateways();

	public abstract Datasource<ORG, ID, PIDSYSTEM> setAffiliatedProvideGateways(final String[] affiliatedProvideGateways);

}
