package eu.dnetlib.domain.functionality;

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

import eu.dnetlib.domain.SearchCriteria;
import eu.dnetlib.domain.SearchCriteriaImpl;

/**
 * This class represents the search criteria that will be used to lookup for user profiles
 *
 */

public class UserProfileSearchCriteria extends SearchCriteriaImpl implements
		SearchCriteria {
	private String belongsToCommunity = null;
	private String email = null;
	private String activationId = null;
	private Boolean active = null;
	private List<String> identities = new ArrayList<String>();
	private List<CommunityRegistration> communityRegs = new ArrayList<CommunityRegistration>();

	public String getActivationId() {
		return activationId;
	}

	public void setActivationId(String activationId) {
		this.activationId = activationId;
	}

	public Boolean getActive() {
		return active;
	}

	public void setActive(Boolean active) {
		this.active = active;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getBelongsToCommunity() {
		return belongsToCommunity;
	}

	public void setBelongsToCommunity(String belongsToCommunity) {
		this.belongsToCommunity = belongsToCommunity;
	}

	/**
	 * Checks if the given object matches the search criteria. If the object that is 
	 * passed as parameter is not of type UserProfile, then <code>matches()</code> will return false. 
	 * @return returns true if the object matches the search criteria
	 */
	public boolean matches(Object o) {
		if (!(o instanceof UserProfileSearchCriteria))
			return false;
		UserProfile profile = (UserProfile) o;

		if (this.getContains() != null) {
			if (profile.getEmail() == null
					|| !profile.getEmail().toLowerCase().contains(
							this.getContains().toLowerCase()))
				return false;
		}

		if (this.getStartsWith() != null) {
			if (profile.getEmail() == null
					|| !profile.getEmail().toLowerCase().startsWith(
							this.getStartsWith().toLowerCase()))
				return false;
		}

		if (this.getEndsWith() != null) {
			if (profile.getEmail() == null
					|| !profile.getEmail().toLowerCase().endsWith(
							this.getEndsWith().toLowerCase()))
				return false;
		}

		if (this.getEmail() != null) {
			if (profile.getEmail() == null
					|| !profile.getEmail().equals(this.getEmail()))
				return false;
		}

		if (this.getActivationId() != null) {
			if (profile.getActivationId() == null
					|| !profile.getActivationId()
							.equals(this.getActivationId()))
				return false;
		}

		if (this.getActive() != null) {
			if ( profile.getActive() != this.getActive())
				return false;
		}

		if (this.getBelongsToCommunity() != null) {
			if (profile.getCommunities() == null
					|| profile.getCommunities().size() == 0)
				return false;
			else {
				boolean found = false;

				for (CommunityRegistration commReg : profile.getCommunities()) {
					if (commReg.getCommunityId().equals(
							this.getBelongsToCommunity())) {
						found = true;

						break;
					}
				}

				if (!found)
					return false;
			}
		}

		return true;
	}

	public boolean equals(Object o) {
		if (!(o instanceof UserProfileSearchCriteria))
			return false;
		else
			return this.equals((UserProfileSearchCriteria) o);
	}

	public boolean equals(UserProfileSearchCriteria crit) {
		if (!super.equals(crit))
			return false;

		if (active != null && crit.active != null) {
			if (!active.equals(crit.active))
				return false;
		} else if ((active == null && crit.active != null)
				|| (active != null && crit.active == null)) {
			return false;
		}

		if (activationId != null && crit.activationId != null) {
			if (!activationId.equals(crit.activationId))
				return false;
		} else if ((activationId == null && crit.activationId != null)
				|| (activationId != null && crit.activationId == null)) {
			return false;
		}

		if (email != null && crit.email != null) {
			if (!email.equals(crit.email))
				return false;
		} else if ((email == null && crit.email != null)
				|| (email != null && crit.email == null)) {
			return false;
		}

		if (belongsToCommunity != null && crit.belongsToCommunity != null) {
			if (!belongsToCommunity.equals(crit.belongsToCommunity))
				return false;
		} else if ((belongsToCommunity == null && crit.belongsToCommunity != null)
				|| (belongsToCommunity != null && crit.belongsToCommunity == null)) {
			return false;
		}

		//check identities		
		if (identities.size() != crit.getIdentities().size()) //different size
		{
			return false;
		} else {
			//check each identity
			for (String identity : identities) {
				if (!crit.getIdentities().contains(identity)) {
					return false;
				}
			}
		}

		if (this.communityRegs.size() != crit.getCommunityRegs().size())

		{
			return false;
		}

		for (CommunityRegistration comReg : this.communityRegs) {
			if (!crit.getCommunityRegs().contains(comReg)) {
				return false;
			}
		}

		return true;
	}

	public int hashCode() {
		int code = super.hashCode();

		if (belongsToCommunity != null)
			code |= belongsToCommunity.hashCode();

		if (email != null)
			code |= email.hashCode();

		if (activationId != null)
			code |= activationId.hashCode();

		if (active != null)
			code |= active.hashCode();

		return code;
	}

	public List<String> getIdentities() {
		return identities;
	}

	public void setIdentities(List<String> identities) {
		this.identities = identities;
	}

	public List<CommunityRegistration> getCommunityRegs() {
		return communityRegs;
	}

	public void setCommunityRegs(List<CommunityRegistration> communityRegs) {
		this.communityRegs = communityRegs;
	}
}
