package com.tandbergtv.watchpoint.pmm.entities;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Service implements java.io.Serializable, IContainer {
	// id for all services not yet in db
	public static final int DEFAULT_ID = 0;
	private static final int HASHCODE_MULTIPLICATION_FACTOR = 8;
	private static final int HASHCODE_ADDITION_FACTOR = 141;	

	private static final long serialVersionUID = 3244668115079364870L;
	private long id;
	private String name;
	private String description;
	private Context context;
	private Set<Partner> partners;
	private Boolean isActive;
	private static String SERVICE_NAME = "Name";
	private static String SERVICE_ID = "Id";
	private static String SERVICE_CONTEXT_ID = "ContextId";
	private String lookupKey;
	
	public Service() {
		context = new ServiceContext();
		((ServiceContext)context).setContainer(this);
	}
	
	public Service(long serviceId) {
		this.id = serviceId;
	}

	public void setId(long id) {
		this.id = id;
	}

	public long getId() {
		return id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getDescription() {
		return description;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	public Context getContext() {
		return context;
	}

	public void setPartners(Set<Partner> partners) {
		this.partners = partners;
	}

	public Set<Partner> getPartners() {
		return partners;
	}

	public int getPartnerCount() {
		return (this.partners != null) ? this.partners.size() : 0;
	}

	public void addPartner(Partner p) {
		if (getPartnerCount() == 0) {
			Set<Partner> partnerSet = new HashSet<Partner>();
			partnerSet.add(p);
			setPartners(partnerSet);
		} else {
			getPartners().add(p);
		}
	}

	public String getContainerName() {
		return this.getName();
	}

	public long getContainerContextId() {
		return this.getContext().getId();
	}

	public long getContainerId() {
		return this.id;
	}
	
	public String getContainerLookupKey() {
		return this.lookupKey;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.entities.IContainer#getType()
	 */
	public ContainerType getContainerType() {
		return ContainerType.SERVICE;
	}

	/**
	 * @return the isActive
	 */
	public Boolean getIsActive() {
		return isActive;
	}

	/**
	 * @param isActive the isActive to set
	 */
	public void setIsActive(Boolean isActive) {
		this.isActive = isActive;
	}

	/**
	 * @return the lookupKey
	 */
	public String getLookupKey() {
		return lookupKey;
	}

	/**
	 * @param lookupKey the lookupKey to set
	 */
	public void setLookupKey(String lookupKey) {
		this.lookupKey = lookupKey;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Service) {
			Service serviceObj = (Service) obj;

			if (serviceObj.getId() != DEFAULT_ID && this.getId() != DEFAULT_ID) {
				return (serviceObj.getId() == this.getId());
			} else {
				return super.equals(obj);
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		long hash = this.id * HASHCODE_MULTIPLICATION_FACTOR
				+ HASHCODE_ADDITION_FACTOR;
		int hashCode = new Long(hash).hashCode();
		if (this.id == DEFAULT_ID) {
			hashCode = super.hashCode();
		}
		return hashCode;
	}	
	
	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.IContainer#getValue(java.lang.String)
	 */
	public String getValue(String propertyName) {
		// this method is used for evaluation of parameter references
		if (propertyName.equalsIgnoreCase(SERVICE_CONTEXT_ID)) {
			return String.valueOf(this.context.getId());
		} else if (propertyName.equalsIgnoreCase(SERVICE_ID)) {
			return String.valueOf(this.id);
		} else if (propertyName.equalsIgnoreCase(SERVICE_NAME)) {
			return this.name;
		}

		return new String();
	}

	@Override
	public List<ContainerProperty> getProperties() {
		return this.getContext().getProperties();
	}

	@Override
	public void setProperties(List<ContainerProperty> properties) {
		this.getContext().setProperties(properties);
	}

	@Override
	public void addProperty(String name, String value) {
		this.getContext().addProperty(name, value);
	}

	@Override
	public void removeProperty(String name) {
		this.getContext().removeProperty(name);
	}
	
	@Override
	public void removeAllProperties() {
		this.context.getProperties().clear();
	}
}
