package eu.dnetlib.domain.data;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eu.dnetlib.domain.DriverResource;

/**
 * The domain object for the Repository resource data structure
 * 
 */
public class Repository extends DriverResource {
	private static final long serialVersionUID = -7241644234046760972L;

	private String typology = null;
	private String adminEmail = null;
	private String country = null;
	private String officialName = null;
	private String englishName = null;
	private String repositoryInstitution = null;
	private String entryUrl = null; // this is the repository web page;
	private String iconUrl = null;
	private String description = null;
	private String availableDiskSpace = null;
	private String securityParameters = null;
	private String protocol = null;
	
	private String registeredBy = null;

	private Integer numberOfObjects = Integer.valueOf(0);
	private Integer maxSizeOfDatastructure = Integer.valueOf(0);
	private Integer maxNumberOfDataStructures = Integer.valueOf(0);

	private double longtitude;
	private double latitude;
	private float timezone = 0; // as decimal offset from GMT
	
	// QOS parameters
	private String availability = null;
	private String capacity = null;
	private Integer responseTime = null;
	private double throughput = 0.0D;

	//status parameters
	private Integer handledDatastructure = null;
	private Integer usedDiskspace = null;
	private Date lastUpdate = null;

	// blackboard
	private RepositoryBlackboard blackboard = null;

    private Map<String, String> extraFields = new HashMap<String, String>();
	
	// extra fields that need to be added to the XML schema
	private String administratorEmail = null;
	private String administratorName = null;
	private String administratorContactInfo = null;

	private List<RepositoryInterface> interfaces = new ArrayList<RepositoryInterface>();

	public Repository() {
		this.setDateOfCreation(new Date());
		this.setResourceKind("RepositoryServiceResources");
		this.setResourceType("RepositoryServiceResourceType");
	}

	public Map<String, String> getExtraFields() {
		return extraFields;
	}

	public void setExtraFields(Map<String, String> extraFields) {
		this.extraFields = extraFields;
	}
	
	public String getRegisteredBy() {
		return registeredBy;
	}

	public void setRegisteredBy(String registeredBy) {
		this.registeredBy = registeredBy;
	}
	
	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getEnglishName() {
		return englishName;
	}

	public void setEnglishName(String englishName) {
		this.englishName = englishName;
	}

	public String getEntryUrl() {
		return entryUrl;
	}

	public void setEntryUrl(String entryUrl) {
		this.entryUrl = entryUrl;
	}

	public String getIconUrl() {
		return iconUrl;
	}

	public void setIconUrl(String iconUrl) {
		this.iconUrl = iconUrl;
	}

	public String getId() {
		return this.getResourceId();
	}

	public void setId(String id) {
		this.setResourceId(id);
	}

	public Integer getNumberOfObjects() {
		return numberOfObjects;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setNumberOfObjects(Integer numberOfObjects) {
		this.numberOfObjects = numberOfObjects;
	}

	public String getOfficialName() {
		return officialName;
	}

	public void setOfficialName(String officialName) {
		this.officialName = officialName;
	}

	public Date getRegistrationDate() {
		return this.getDateOfCreation();
	}

	public void setRegistrationDate(Date registrationDate) {
		this.setDateOfCreation(registrationDate);
	}

	public List<RepositoryInterface> getInterfaces() {
		return interfaces;
	}

	public void setInterfaces(List<RepositoryInterface> interfaces) {
		this.interfaces = interfaces;
	}

	public String getTypology() {
		return typology;
	}

	public void setTypology(String typology) {
		this.typology = typology;
	}

	public double getLongtitude() {
		return longtitude;
	}

	public void setLongtitude(double longtitude) {
		this.longtitude = longtitude;
	}

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public float getTimezone() {
		return timezone;
	}

	public void setTimezone(float timezone) throws IllegalArgumentException {
		if (timezone < -12 || timezone > 12 || (timezone % 0.5) != 0) {
			String t = String.valueOf(timezone);
			throw new IllegalArgumentException(
					"timezone must be in the range [-12.0, 12.0] and must me divided by 0.5. Value given is "
							+ t);
		}
		this.timezone = timezone;
	}

	public String getAdministratorName() {
		return administratorName;
	}

	public void setAdministratorName(String administratorName) {
		this.administratorName = administratorName;
	}

	public String getAdministratorContactInfo() {
		return administratorContactInfo;
	}

	public void setAdministratorContactInfo(String administratorContactInfo) {
		this.administratorContactInfo = administratorContactInfo;
	}

	public String getRepositoryInstitution() {
		return repositoryInstitution;
	}

	public void setRepositoryInstitution(String repositoryInstitution) {
		this.repositoryInstitution = repositoryInstitution;
	}

	public String getAdministratorEmail() {
		return administratorEmail;
	}

	public void setAdministratorEmail(String administratorEmail) {
		this.administratorEmail = administratorEmail;
	}

	public boolean equals(Object o) {
		if (!(o instanceof Repository))
			return false;
		else
			return this.equals((Repository) o);
	}

	public boolean equals(Repository r) {
		// TODO: fill with required fields...

		if (this.getOfficialName() != null && r.getOfficialName() == null) {
			return false;
		} else if (this.getOfficialName() == null
				&& r.getOfficialName() != null) {
			return false;
		} else if (this.getOfficialName() != null
				&& r.getOfficialName() != null) {
			return this.getOfficialName().equals(r.getOfficialName());
		}

		return true;
	}

	@Override
	public int hashCode() {
		return officialName.hashCode();
	}

	public String getAdminEmail() {
		return adminEmail;
	}

	public void setAdminEmail(String adminEmail) {
		this.adminEmail = adminEmail;
	}

	public String getAvailableDiskSpace() {
		return availableDiskSpace;
	}

	public void setAvailableDiskSpace(String availableDiskSpace) {
		this.availableDiskSpace = availableDiskSpace;
	}

	public String getSecurityParameters() {
		return securityParameters;
	}

	public void setSecurityParameters(String securityParameters) {
		this.securityParameters = securityParameters;
	}

	public Integer getMaxSizeOfDatastructure() {
		return maxSizeOfDatastructure;
	}

	public void setMaxSizeOfDatastructure(Integer maxSizeOfDatastructure) {
		this.maxSizeOfDatastructure = maxSizeOfDatastructure;
	}

	public Integer getMaxNumberOfDataStructures() {
		return maxNumberOfDataStructures;
	}

	public void setMaxNumberOfDataStructures(Integer maxNumberOfDataStructures) {
		this.maxNumberOfDataStructures = maxNumberOfDataStructures;
	}

	public String getAvailability() {
		return availability;
	}

	public void setAvailability(String availability) {
		this.availability = availability;
	}

	public String getCapacity() {
		return capacity;
	}

	public void setCapacity(String capacity) {
		this.capacity = capacity;
	}

	public Integer getResponseTime() {
		return responseTime;
	}

	public void setResponseTime(Integer responseTime) {
		this.responseTime = responseTime;
	}

	public double getThroughput() {
		return throughput;
	}

	public void setThroughput(double throughput) {
		this.throughput = throughput;
	}

	public Integer getHandledDatastructure() {
		return handledDatastructure;
	}

	public void setHandledDatastructure(Integer handledDatastructure) {
		this.handledDatastructure = handledDatastructure;
	}

	public Integer getUsedDiskspace() {
		return usedDiskspace;
	}

	public void setUsedDiskspace(Integer usedDiskspace) {
		this.usedDiskspace = usedDiskspace;
	}

	public Date getLastUpdate() {
		return lastUpdate;
	}

	public void setLastUpdate(Date lastUpdate) {
		this.lastUpdate = lastUpdate;
	}

	public String getProtocol() {
		return protocol;
	}

	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}

	public RepositoryBlackboard getBlackboard() {
		return blackboard;
	}

	public void setBlackboard(RepositoryBlackboard blackboard) {
		this.blackboard = blackboard;
	}
	
	public String getVerified(){
		if(this.getExtraFields().isEmpty() || this.getExtraFields().get("VERIFIED").equals("YES"))
			return "VERIFIED";
		else
			return null;
	}
}