/*******************************************************************************
 * Copyright (c) 2008, 2009 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.eclipselink.core.internal.context.persistence.EclipseLinkPersistenceUnitProperties;
import org.eclipse.jpt.utility.internal.CollectionTools;

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

	// key = Entity name ; value = Cache properties
	private Map<String, CacheProperties> entitiesCacheProperties;
	
	// ********** constructors **********
	public EclipseLinkCaching(PersistenceUnit parent) {
		super(parent);
	}

	// ********** 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);
		this.flushClearCache = 
			this.getEnumValue(ECLIPSELINK_FLUSH_CLEAR_CACHE, FlushClearCache.values());
		
		Set<PersistenceUnit.Property> cacheTypeProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_CACHE_TYPE);
		Set<PersistenceUnit.Property> cacheSizeProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_CACHE_SIZE);
		Set<PersistenceUnit.Property> sharedCacheProperties = 
			this.getPropertiesSetWithPrefix(ECLIPSELINK_SHARED_CACHE);
		
		this.initializeEntitiesCacheType(cacheTypeProperties);
		this.initializeEntitiesCacheSize(cacheSizeProperties);
		this.initializeEntitiesSharedCache(sharedCacheProperties);
	}

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

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

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

	// ********** behavior **********
	
	public void propertyValueChanged(String propertyName, String newValue) {
		if (propertyName.equals(ECLIPSELINK_CACHE_TYPE_DEFAULT)) {
			this.cacheTypeDefaultChanged(newValue);
		}
		else if (propertyName.equals(ECLIPSELINK_CACHE_SIZE_DEFAULT)) {
			this.cacheSizeDefaultChanged(newValue);
		}
		else if (propertyName.equals(ECLIPSELINK_CACHE_SHARED_DEFAULT)) {
			this.sharedCacheDefaultChanged(newValue);
		}
		else if (propertyName.startsWith(ECLIPSELINK_CACHE_TYPE)) {
			this.cacheTypeChanged(propertyName, newValue);
		}
		else if (propertyName.startsWith(ECLIPSELINK_CACHE_SIZE)) {
			this.cacheSizeChanged(propertyName, newValue);
		}
		else if (propertyName.startsWith(ECLIPSELINK_SHARED_CACHE)) {
			this.sharedCacheChanged(propertyName, newValue);
		}
		else if (propertyName.equals(ECLIPSELINK_FLUSH_CLEAR_CACHE)) {
			this.flushClearCacheChanged(newValue);
		}
	}
	
	public void propertyRemoved(String propertyName) {
		if (propertyName.equals(ECLIPSELINK_CACHE_TYPE_DEFAULT)) {
			this.cacheTypeDefaultChanged(null);
		}
		else if (propertyName.equals(ECLIPSELINK_CACHE_SIZE_DEFAULT)) {
			this.cacheSizeDefaultChanged(null);
		}
		else if (propertyName.equals(ECLIPSELINK_CACHE_SHARED_DEFAULT)) {
			this.sharedCacheDefaultChanged(null);
		}
		else if (propertyName.startsWith(ECLIPSELINK_CACHE_TYPE)) {
			this.cacheTypeChanged(propertyName, null);
		}
		else if (propertyName.startsWith(ECLIPSELINK_CACHE_SIZE)) {
			this.cacheSizeChanged(propertyName, null);
		}
		else if (propertyName.startsWith(ECLIPSELINK_SHARED_CACHE)) {
			this.sharedCacheChanged(propertyName, null);
		}
		else if (propertyName.equals(ECLIPSELINK_FLUSH_CLEAR_CACHE)) {
			this.flushClearCacheChanged(null);
		}
	}
	
	/**
	 * 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);
		propertyNames.put(
			ECLIPSELINK_FLUSH_CLEAR_CACHE,
			FLUSH_CLEAR_CACHE_PROPERTY);
		
		// Don't need to initialize propertyNames for: 
		// cacheType, sharedCache, cacheSize
	}

	/**
	 * Method used for identifying the given property.
	 */
	@Override
	public boolean itemIsProperty(PersistenceUnit.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(PersistenceUnit.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());
	}

	// ********** 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(String propertyName, String stringValue) {
		String entityName = this.getEntityName(propertyName);
		CacheProperties old = this.setCacheType_(stringValue, entityName);
		this.firePropertyChanged(CACHE_TYPE_PROPERTY, 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(String propertyName, String stringValue) {
		String entityName = this.getEntityName(propertyName);
		CacheProperties old = this.setCacheSize_(stringValue, entityName);
		this.firePropertyChanged(CACHE_SIZE_PROPERTY, 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(String propertyName, String stringValue) {
		String entityName = this.getEntityName(propertyName);
		CacheProperties old = this.setSharedCache_(stringValue, entityName);
		this.firePropertyChanged(SHARED_CACHE_PROPERTY, 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(String stringValue) {
		CacheType newValue = getEnumValueOf(stringValue, CacheType.values());
		CacheType old = this.cacheTypeDefault;
		this.cacheTypeDefault = newValue;
		this.firePropertyChanged(CACHE_TYPE_DEFAULT_PROPERTY, 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(String stringValue) {
		Integer newValue = getIntegerValueOf(stringValue);
		Integer old = this.cacheSizeDefault;
		this.cacheSizeDefault = newValue;
		this.firePropertyChanged(CACHE_SIZE_DEFAULT_PROPERTY, 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(String stringValue) {
		Boolean newValue = getBooleanValueOf(stringValue);
		
		Boolean old = this.sharedCacheDefault;
		this.sharedCacheDefault = newValue;
		this.firePropertyChanged(SHARED_CACHE_DEFAULT_PROPERTY, old, newValue);
	}

	public Boolean getDefaultSharedCacheDefault() {
		return DEFAULT_SHARED_CACHE_DEFAULT;
	}

	// ********** FlushClearCache **********
	
	public FlushClearCache getFlushClearCache() {
		return this.flushClearCache;
	}
	
	public void setFlushClearCache(FlushClearCache newFlushClearCache) {
		FlushClearCache old = this.flushClearCache;
		this.flushClearCache = newFlushClearCache;
		this.putProperty(FLUSH_CLEAR_CACHE_PROPERTY, newFlushClearCache);
		this.firePropertyChanged(FLUSH_CLEAR_CACHE_PROPERTY, old, newFlushClearCache);
	}

	private void flushClearCacheChanged(String stringValue) {
		FlushClearCache newValue = getEnumValueOf(stringValue, FlushClearCache.values());
		FlushClearCache old = this.flushClearCache;
		this.flushClearCache = newValue;
		this.firePropertyChanged(FLUSH_CLEAR_CACHE_PROPERTY, old, newValue);
	}
	
	public FlushClearCache getDefaultFlushClearCache() {
		return DEFAULT_FLUSH_CLEAR_CACHE;
	}

	// ****** CacheProperties *******
	/**
	 * Convenience method to update the CacheType in entitiesCache map. Returns
	 * the old value of CacheProperties
	 */
	private CacheProperties setCacheType_(String stringValue, String entityName) {
		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_(String stringValue, String entityName) {
		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_(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 exists.");
		}
		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);
	}
}
