/*******************************************************************************
 * Copyright (c) 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 *******************************************************************************/
package org.eclipse.jpt.eclipselink.core.internal.context.persistence.caching;

import java.util.HashMap;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.core.context.persistence.Property;
import org.eclipse.jpt.eclipselink.core.internal.context.persistence.EclipseLinkPersistenceUnitProperties;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.utility.model.value.ListValueModel;

/**
 * EclipseLinkCaching encapsulates EclipseLink Caching properties.
 */
public class EclipseLinkCaching extends EclipseLinkPersistenceUnitProperties
	implements Caching
{
	// ********** EclipseLink properties **********
	private CacheType cacheTypeDefault;
	private Integer cacheSizeDefault;
	private Boolean sharedCacheDefault;

	// key = Entity name ; value = Cache properties
	private Map<String, CacheProperties> entitiesCacheProperties;

	private static final long serialVersionUID = 1L;
	
	// ********** constructors **********
	public EclipseLinkCaching(PersistenceUnit parent, ListValueModel<Property> propertyListAdapter) {
		super(parent, propertyListAdapter);
	}

	// ********** initialization **********
	/**
	 * Initializes properties with values from the persistence unit.
	 */
	@Override
	protected void initializeProperties() {
		// TOREVIEW - handle incorrect String in persistence.xml
		this.entitiesCacheProperties = 
			new HashMap<String, CacheProperties>();
		this.cacheTypeDefault = 
			this.getEnumValue(ECLIPSELINK_CACHE_TYPE_DEFAULT, CacheType.values());
		this.cacheSizeDefault = 
			this.getIntegerValue(ECLIPSELINK_CACHE_SIZE_DEFAULT);
		this.sharedCacheDefault = 
			this.getBooleanValue(ECLIPSELINK_CACHE_SHARED_DEFAULT);
		
		Set<Property> cacheTypeProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_CACHE_TYPE);
		Set<Property> cacheSizeProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_CACHE_SIZE);
		Set<Property> sharedCacheProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_SHARED_CACHE);
		
		this.initializeEntitiesCacheType(cacheTypeProperties);
		this.initializeEntitiesCacheSize(cacheSizeProperties);
		this.initializeEntitiesSharedCache(sharedCacheProperties);
	}

	private void initializeEntitiesCacheType(Set<Property> properties) {
		for (Property property : properties) {
			String entityName = this.getEntityName(property);
			CacheType cacheType = getEnumValueOf(property.getValue(), CacheType.values());
			this.setCacheType_(cacheType, entityName);
		}
	}

	private void initializeEntitiesCacheSize(Set<Property> properties) {
		for (Property property : properties) {
			String entityName = this.getEntityName(property);
			this.setCacheSize_(property, entityName);
		}
	}

	private void initializeEntitiesSharedCache(Set<Property> properties) {
		for (Property property : properties) {
			String entityName = this.getEntityName(property);
			this.setSharedCache_(property, entityName);
		}
	}

	// ********** behavior **********
	/**
	 * Adds property names key/value pairs, where: 
	 * 		key = EclipseLink property key;
	 * 		value = property id
	 */
	@Override
	protected void addPropertyNames(Map<String, String> propertyNames) {
		propertyNames.put(
			ECLIPSELINK_CACHE_TYPE_DEFAULT,
			CACHE_TYPE_DEFAULT_PROPERTY);
		propertyNames.put(
			ECLIPSELINK_CACHE_SIZE_DEFAULT,
			CACHE_SIZE_DEFAULT_PROPERTY);
		propertyNames.put(
			ECLIPSELINK_CACHE_SHARED_DEFAULT,
			SHARED_CACHE_DEFAULT_PROPERTY);
		
		// Don't need to initialize propertyNames for: 
		// cacheType, sharedCache, cacheSize
	}

	/**
	 * Method used for identifying the given property.
	 */
	@Override
	public boolean itemIsProperty(Property item) {
		boolean isProperty = super.itemIsProperty(item);
		
		if ( ! isProperty && item.getName() != null) {
				if (item.getName().startsWith(ECLIPSELINK_CACHE_TYPE) || 
						item.getName().startsWith(ECLIPSELINK_CACHE_SIZE) || 
						item.getName().startsWith(ECLIPSELINK_SHARED_CACHE)) {
					return true;
				}
		}
		return isProperty;
	}

	/**
	 * Returns the property name used for change notification of the given
	 * property.
	 */
	@Override
	public String propertyIdFor(Property property) {
		try {
			return super.propertyIdFor(property);
		}
		catch (IllegalArgumentException e) {
			if (property.getName().startsWith(ECLIPSELINK_CACHE_TYPE)) {
				return CACHE_TYPE_PROPERTY;
			}
			else if (property.getName().startsWith(ECLIPSELINK_CACHE_SIZE)) {
				return CACHE_SIZE_PROPERTY;
			}
			else if (property.getName().startsWith(ECLIPSELINK_SHARED_CACHE)) {
				return SHARED_CACHE_PROPERTY;
			}
		}
		throw new IllegalArgumentException("Illegal property: " + property.toString());
	}

	public void propertyChanged(PropertyChangeEvent event) {
		String aspectName = event.getAspectName();
		if (aspectName.equals(CACHE_TYPE_DEFAULT_PROPERTY)) {
			this.cacheTypeDefaultChanged(event);
		}
		else if (aspectName.equals(CACHE_SIZE_DEFAULT_PROPERTY)) {
			this.cacheSizeDefaultChanged(event);
		}
		else if (aspectName.equals(SHARED_CACHE_DEFAULT_PROPERTY)) {
			this.sharedCacheDefaultChanged(event);
		}
		else if (aspectName.equals(CACHE_TYPE_PROPERTY)) {
			this.cacheTypeChanged(event);
		}
		else if (aspectName.equals(CACHE_SIZE_PROPERTY)) {
			this.cacheSizeChanged(event);
		}
		else if (aspectName.equals(SHARED_CACHE_PROPERTY)) {
			this.sharedCacheChanged(event);
		}
		else {
			throw new IllegalArgumentException("Illegal event received - property not applicable: " + aspectName);
		}
		return;
	}

	// ********** CacheType **********
	public CacheType getCacheType(String entityName) {
		CacheProperties cache = this.cachePropertiesOf(entityName);
		return (cache == null) ? null : cache.getType();
	}

	public void setCacheType(CacheType newCacheType, String entityName) {
		CacheProperties old = this.setCacheType_(newCacheType, entityName);
		this.putEnumValue(ECLIPSELINK_CACHE_TYPE, entityName, newCacheType, false);
		this.firePropertyChanged(CACHE_TYPE_PROPERTY, old, this.cachePropertiesOf(entityName));
	}

	private void cacheTypeChanged(PropertyChangeEvent event) {
		Property property = (Property) event.getNewValue();
		// property == null when removed
		String entityName = (property == null) ? this.getEntityName((Property) event.getOldValue()) : this.getEntityName(property);
		CacheProperties old = this.setCacheType_(property, entityName);
		this.firePropertyChanged(event.getAspectName(), old, this.cachePropertiesOf(entityName));
	}

	public CacheType getDefaultCacheType() {
		return (this.cacheTypeDefault == null) ? DEFAULT_CACHE_TYPE : this.cacheTypeDefault;
	}

	// ********** CacheSize **********
	public Integer getCacheSize(String entityName) {
		CacheProperties cache = this.cachePropertiesOf(entityName);
		return (cache == null) ? null : cache.getSize();
	}

	public void setCacheSize(Integer newCacheSize, String entityName) {
		CacheProperties old = this.setCacheSize_(newCacheSize, entityName);
		this.putIntegerValue(ECLIPSELINK_CACHE_SIZE + entityName, newCacheSize);
		this.firePropertyChanged(CACHE_SIZE_PROPERTY, old, this.cachePropertiesOf(entityName));
	}

	private void cacheSizeChanged(PropertyChangeEvent event) {
		Property property = (Property) event.getNewValue();
		// property == null when removed
		String entityName = (property == null) ? this.getEntityName((Property) event.getOldValue()) : this.getEntityName(property);
		CacheProperties old = this.setCacheSize_(property, entityName);
		this.firePropertyChanged(event.getAspectName(), old, this.cachePropertiesOf(entityName));
	}

	public Integer getDefaultCacheSize() {
		return (this.cacheSizeDefault == null) ? DEFAULT_CACHE_SIZE : this.cacheSizeDefault;
	}

	// ********** SharedCache **********
	public Boolean getSharedCache(String entityName) {
		CacheProperties cache = this.cachePropertiesOf(entityName);
		return (cache == null) ? null : cache.isShared();
	}

	public void setSharedCache(Boolean newSharedCache, String entityName) {
		CacheProperties old = this.setSharedCache_(newSharedCache, entityName);
		this.putBooleanValue(ECLIPSELINK_SHARED_CACHE, entityName, newSharedCache, false);
		this.firePropertyChanged(SHARED_CACHE_PROPERTY, old, this.cachePropertiesOf(entityName));
	}

	private void sharedCacheChanged(PropertyChangeEvent event) {
		String entityName;
		Property newProperty = (Property) event.getNewValue();
		// property == null when removed
		entityName = (newProperty == null) ? 
			this.getEntityName((Property) event.getOldValue()) : this.getEntityName(newProperty);
		CacheProperties old = this.setSharedCache_(newProperty, entityName);
		this.firePropertyChanged(event.getAspectName(), old, this.cachePropertiesOf(entityName));
	}

	public Boolean getDefaultSharedCache() {
		return (this.sharedCacheDefault == null) ? DEFAULT_SHARED_CACHE : this.sharedCacheDefault;
	}

	// ********** CacheTypeDefault **********
	public CacheType getCacheTypeDefault() {
		return this.cacheTypeDefault;
	}

	public void setCacheTypeDefault(CacheType newCacheTypeDefault) {
		CacheType old = this.cacheTypeDefault;
		this.cacheTypeDefault = newCacheTypeDefault;
		this.putProperty(CACHE_TYPE_DEFAULT_PROPERTY, newCacheTypeDefault);
		this.firePropertyChanged(CACHE_TYPE_DEFAULT_PROPERTY, old, newCacheTypeDefault);
	}

	private void cacheTypeDefaultChanged(PropertyChangeEvent event) {
		String stringValue = (event.getNewValue() == null) ? null : ((Property) event.getNewValue()).getValue();
		CacheType newValue = getEnumValueOf(stringValue, CacheType.values());
		CacheType old = this.cacheTypeDefault;
		this.cacheTypeDefault = newValue;
		this.firePropertyChanged(event.getAspectName(), old, newValue);
	}

	public CacheType getDefaultCacheTypeDefault() {
		return DEFAULT_CACHE_TYPE_DEFAULT;
	}

	// ********** CacheSizeDefault **********
	public Integer getCacheSizeDefault() {
		return this.cacheSizeDefault;
	}

	public void setCacheSizeDefault(Integer newCacheSizeDefault) {
		Integer old = this.cacheSizeDefault;
		this.cacheSizeDefault = newCacheSizeDefault;
		this.putProperty(CACHE_SIZE_DEFAULT_PROPERTY, newCacheSizeDefault);
		this.firePropertyChanged(CACHE_SIZE_DEFAULT_PROPERTY, old, newCacheSizeDefault);
	}

	private void cacheSizeDefaultChanged(PropertyChangeEvent event) {
		String stringValue = (event.getNewValue() == null) ? null : ((Property) event.getNewValue()).getValue();
		Integer newValue = getIntegerValueOf(stringValue);
		Integer old = this.cacheSizeDefault;
		this.cacheSizeDefault = newValue;
		this.firePropertyChanged(event.getAspectName(), old, newValue);
	}

	public Integer getDefaultCacheSizeDefault() {
		return DEFAULT_CACHE_SIZE_DEFAULT;
	}

	// ********** SharedCacheDefault **********
	public Boolean getSharedCacheDefault() {
		return this.sharedCacheDefault;
	}

	public void setSharedCacheDefault(Boolean newSharedCacheDefault) {
		Boolean old = this.sharedCacheDefault;
		this.sharedCacheDefault = newSharedCacheDefault;
		this.putProperty(SHARED_CACHE_DEFAULT_PROPERTY, newSharedCacheDefault);
		this.firePropertyChanged(SHARED_CACHE_DEFAULT_PROPERTY, old, newSharedCacheDefault);
	}

	private void sharedCacheDefaultChanged(PropertyChangeEvent event) {
		String stringValue = (event.getNewValue() == null) ? null : ((Property) event.getNewValue()).getValue();
		Boolean newValue = getBooleanValueOf(stringValue);
		
		Boolean old = this.sharedCacheDefault;
		this.sharedCacheDefault = newValue;
		this.firePropertyChanged(event.getAspectName(), old, newValue);
	}

	public Boolean getDefaultSharedCacheDefault() {
		return DEFAULT_SHARED_CACHE_DEFAULT;
	}

	// ****** CacheProperties *******
	/**
	 * Convenience method to update the CacheType in entitiesCache map. Returns
	 * the old value of CacheProperties
	 */
	private CacheProperties setCacheType_(Property newProperty, String entityName) {
		String stringValue = (newProperty == null) ? null : newProperty.getValue();
		CacheType newValue = getEnumValueOf(stringValue, CacheType.values());
		return this.setCacheType_(newValue, entityName);
	}

	private CacheProperties setCacheType_(CacheType newValue, String entityName) {
		CacheProperties properties = this.cachePropertiesOf(entityName);
		CacheProperties old = properties.clone();
		properties.setType(newValue);
		this.putEntityCacheProperties(entityName, properties);
		return old;
	}

	/**
	 * Convenience method to update the CacheSize in entitiesCache map. Returns
	 * the old value of CacheProperties
	 */
	private CacheProperties setCacheSize_(Property newProperty, String entityName) {
		String stringValue = (newProperty == null) ? null : newProperty.getValue();
		Integer newValue = getIntegerValueOf(stringValue);
		return this.setCacheSize_(newValue, entityName);
	}

	private CacheProperties setCacheSize_(Integer newValue, String entityName) {
		CacheProperties properties = this.cachePropertiesOf(entityName);
		CacheProperties old = properties.clone();
		properties.setSize(newValue);
		this.putEntityCacheProperties(entityName, properties);
		return old;
	}

	/**
	 * Convenience method to update the SharedCache in entitiesCacheProperties map.
	 * Returns the old value of CacheProperties
	 */
	private CacheProperties setSharedCache_(Property newProperty, String entityName) {
		String newValue = (newProperty == null) ? null : newProperty.getValue();
		return this.setSharedCache_(newValue, entityName);
	}

	private CacheProperties setSharedCache_(String newString, String entityName) {
		Boolean newValue = getBooleanValueOf(newString);
		return setSharedCache_(newValue, entityName);
	}

	private CacheProperties setSharedCache_(Boolean newValue, String entityName) {
		CacheProperties properties = this.cachePropertiesOf(entityName);
		CacheProperties old = properties.clone();
		properties.setShared(newValue);
		this.putEntityCacheProperties(entityName, properties);
		return old;
	}

	/**
	 * Returns the CacheProperties of the Entity with the given name.
	 */
	private CacheProperties cachePropertiesOf(String entityName) {
		CacheProperties properties = this.entitiesCacheProperties.get(entityName);
		if (properties == null) {
			properties = new CacheProperties(entityName);
		}
		return properties;
	}

	/**
	 * Set all CacheProperties to default.
	 */
	private void clearCacheProperties(String entityName) {
		this.setCacheType(null, entityName);
		this.setCacheSize(null, entityName);
		this.setSharedCache(null, entityName);
	}

	// ****** convenience methods *******

	/**
	 * Put the given Entity CacheProperties in this entitiesCacheProperties map.
	 * @param entityName - Entity name. The entity may be a new or an existing entity.
	 * @param properties - Entity CacheProperties
	 */
	private void putEntityCacheProperties(String entityName, CacheProperties properties) {
		this.addOrReplacePropertiesForEntity(entityName, properties);
	}

	// ****** entities list *******

	public ListIterator<String> entities() {
		return CollectionTools.list(this.entitiesCacheProperties.keySet()).listIterator();
	}

	public int entitiesSize() {
		return this.entitiesCacheProperties.size();
	}

	/* 
	 * Verifies if this entitiesCacheProperties map contains the given Entity. 
	 */
	public boolean entityExists(String entity) {
		return this.entitiesCacheProperties.containsKey(entity);
	}

	public String addEntity(String entity) {
		if (entityExists(entity)) {
			throw new IllegalStateException("Entity " + entity + " already exist.");
		}
		return this.addOrReplacePropertiesForEntity(entity, new CacheProperties(entity));
	}

	/**
	 * Adds or replaces the given Entity CacheProperties in this
	 * entitiesCacheProperties map. 
	 * If the specified Entity exists and the given CacheProperties is empty 
	 * (i.e. all properties are null) the mapping will be removed from the map.
	 * 
	 * @param entity - Entity name
	 * @param properties - Entity CacheProperties
	 * @return Entity name added
	 */
	private String addOrReplacePropertiesForEntity(String entity, CacheProperties properties) {
		if (this.entityExists(entity)) {
			this.replaceEntity_(entity, properties);
			return null;
		}
		this.entitiesCacheProperties.put(entity, properties);
		this.fireListChanged(ENTITIES_LIST_PROPERTY);
		return entity;
	}

	/**
	 * Replaces the given Entity CacheProperties in this
	 * entitiesCacheProperties map.
	 * If the given Entity CacheProperties is empty (i.e. all properties are null) the 
	 * mapping will be removed from the map.
	 * @param entity - Entity name
	 * @param properties - Entity CacheProperties
	 * @return Entity name replaced
	 */
	private CacheProperties replaceEntity_(String entity, CacheProperties properties) {
		CacheProperties old = this.entitiesCacheProperties.get(entity);
		if (properties.isEmpty()) {
			this.entitiesCacheProperties.remove(entity);
			this.fireListChanged(ENTITIES_LIST_PROPERTY);
		}
		else {
			this.entitiesCacheProperties.put(entity, properties);
		}
		return old;
	}

	public void removeEntity(String entity) {
		if ( ! this.entityExists(entity)) {
			return;
		}
		this.clearCacheProperties(entity);
		this.entitiesCacheProperties.remove(entity);
		this.fireListChanged(ENTITIES_LIST_PROPERTY);
	}
}
