package org.wso2.carbon.caching.core.ehcache;

import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.infinispan.manager.DefaultCacheManager;
import org.wso2.carbon.caching.core.CacheConfiguration;
import org.wso2.carbon.caching.core.CarbonCacheManager;

public class EhcacheManager extends net.sf.jsr107cache.CacheManager implements CarbonCacheManager {
    private static final Log log = LogFactory.getLog(EhcacheManager.class);
    private static Boolean lock = new Boolean(true);
    private long maxExpirationMillis = 0;
    private long maxIdleExpirationMillis = 0;
    private int maxEntries = 0;

    public void initialize(String carbonHome) {
        org.wso2.carbon.caching.core.CacheConfiguration cacheConfiguration =
                                                                             org.wso2.carbon.caching.core.CacheConfiguration.getInstance();

        maxExpirationMillis =
                                   cacheConfiguration.getProperty("maxExpirationMillis") == null
                                                                                                ? CacheConfiguration.DEFAULT_EXPIRATION
                                                                                                : Long.parseLong(cacheConfiguration.getProperty("maxExpirationMillis"));

        maxIdleExpirationMillis =
                                       cacheConfiguration.getProperty("maxIdleExpirationMillis") == null
                                                                                                        ? CacheConfiguration.DEFAULT_EXPIRATION
                                                                                                        : Long.parseLong(cacheConfiguration.getProperty("maxIdleExpirationMillis"));

        maxEntries =
                         cacheConfiguration.getProperty("maxEntries") == null
                                                                             ? CacheConfiguration.MAX_ELEMENTS
                                                                             : Integer.parseInt(cacheConfiguration.getProperty("maxEntries"));

        if (log.isDebugEnabled()) {
            log.debug("cache manager initialized");
        }

    }

    public String getDefaultCacheName() {
        return DefaultCacheManager.DEFAULT_CACHE_NAME;
    }

    public Cache getCache(String cacheName) {
		if (cacheName == null) {
			cacheName = DefaultCacheManager.DEFAULT_CACHE_NAME;
		}
        net.sf.ehcache.CacheManager manager = net.sf.ehcache.CacheManager.getInstance();
        Cache cache = manager.getJCache(cacheName);
        if (cache == null) {
            synchronized (lock) {
                cache = manager.getJCache(cacheName);
                if (cache == null) {
                    net.sf.ehcache.config.CacheConfiguration cacheConfig =
                                                                           new net.sf.ehcache.config.CacheConfiguration();

                    cacheConfig.setDiskPersistent(false);
                    cacheConfig.setDiskSpoolBufferSizeMB(0);
                    cacheConfig.setOverflowToDisk(false);
                    cacheConfig.setTimeToIdleSeconds(maxIdleExpirationMillis / 1000L);
                    cacheConfig.setTimeToLiveSeconds(maxExpirationMillis / 1000L);
                    cacheConfig.setMaxElementsInMemory(maxEntries);

                    manager.addCache(cacheName);
                    cache = manager.getJCache(cacheName);
                }
            }
        }
        return cache;
    }

    public CacheFactory getCacheFactory() throws CacheException {
        throw new CacheException(
                                 "The EhcacheCacheManager does not provide an in-built nor look-up a CacheFactory.");
    }

    public void registerCache(String cacheName, Cache cache) {
        throw new RuntimeException("The EhcacheCacheManager does not provide register.");
    }
}

@@ -2826,33 +2826,32 @@
 %0A               
- 
 cache = manager.
@@ -2901,32 +2901,154 @@
 ache == null) %7B%0A
+                    manager.addCache(cacheName);%0A            %09    cache = manager.getJCache(cacheName);%0A            %09    %0A
                 
@@ -3185,34 +3185,39 @@
     
-new net.sf.ehcache.config.
+manager.getCache(cacheName).get
 Cach
@@ -3675,94 +3675,29 @@
     
-manager.addCache(cacheName);%0A                    cache = manager.getJCache(cacheName);
+%0A                    
 %0A   

Fix for CARBON-14767