/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.commons.jcs3.jcache;

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.configuration.CacheEntryListenerConfiguration;
import javax.cache.configuration.CompleteConfiguration;
import javax.cache.configuration.Configuration;
import javax.cache.integration.CompletionListener;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
import javax.cache.processor.EntryProcessorResult;

import static org.apache.commons.jcs3.jcache.Asserts.assertNotNull;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

// kind of transactional view for a Cache<K, V>, to use with EntryProcessor
public class TempStateCacheView<K, V> implements Cache<K, V>
{
    private final JCSCache<K, V> cache;
    private final Map<K, V> put = new HashMap<>();
    private final Collection<K> remove = new LinkedList<>();
    private boolean removeAll;
    private boolean clear;

    public TempStateCacheView(final JCSCache<K, V> entries)
    {
        this.cache = entries;
    }

    @Override
    public V get(final K key)
    {
        if (ignoreKey(key))
        {
            return null;
        }

        final V v = put.get(key);
        if (v != null)
        {
            return v;
        }

        // for an EntryProcessor we already incremented stats - to enhance
        // surely
        if (cache.getConfiguration(CompleteConfiguration.class).isStatisticsEnabled())
        {
            final Statistics statistics = cache.getStatistics();
            if (cache.containsKey(key))
            {
                statistics.increaseHits(-1);
            }
            else
            {
                statistics.increaseMisses(-1);
            }
        }
        return cache.get(key);
    }

    private boolean ignoreKey(final K key)
    {
        return removeAll || clear || remove.contains(key);
    }

    @Override
    public Map<K, V> getAll(final Set<? extends K> keys)
    {
        final Map<K, V> v = new HashMap<>(keys.size());
        final Set<K> missing = new HashSet<>();
        for (final K k : keys)
        {
            final V value = put.get(k);
            if (value != null)
            {
                v.put(k, value);
            }
            else if (!ignoreKey(k))
            {
                missing.add(k);
            }
        }
        if (!missing.isEmpty())
        {
            v.putAll(cache.getAll(missing));
        }
        return v;
    }

    @Override
    public boolean containsKey(final K key)
    {
        return !ignoreKey(key) && (put.containsKey(key) || cache.containsKey(key));
    }

    @Override
    public void loadAll(final Set<? extends K> keys, final boolean replaceExistingValues, final CompletionListener completionListener)
    {
        cache.loadAll(keys, replaceExistingValues, completionListener);
    }

    @Override
    public void put(final K key, final V value)
    {
        assertNotNull(key, "key");
        assertNotNull(value, "value");
        put.put(key, value);
        remove.remove(key);
    }

    @Override
    public V getAndPut(final K key, final V value)
    {
        final V v = get(key);
        put(key, value);
        return v;
    }

    @Override
    public void putAll(final Map<? extends K, ? extends V> map)
    {
        put.putAll(map);
        for (final K k : map.keySet())
        {
            remove.remove(k);
        }
    }

    @Override
    public boolean putIfAbsent(final K key, final V value)
    {
        if (!put.containsKey(key))
        {
            put.put(key, value);
            remove.remove(key);
            return true;
        }
        return false;
    }

    @Override
    public boolean remove(final K key)
    {
        final boolean noop = put.containsKey(key);
        put.remove(key);
        if (!ignoreKey(key))
        {
            if (!noop)
            {
                remove.add(key);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean remove(final K key, final V oldValue)
    {
        put.remove(key);
        if (!ignoreKey(key) && oldValue.equals(cache.get(key)))
        {
            remove.add(key);
            return true;
        }
        return false;
    }

    @Override
    public V getAndRemove(final K key)
    {
        final V v = get(key);
        remove.add(key);
        put.remove(key);
        return v;
    }

    @Override
    public boolean replace(final K key, final V oldValue, final V newValue)
    {
        if (oldValue.equals(get(key)))
        {
            put(key, newValue);
            return true;
        }
        return false;
    }

    @Override
    public boolean replace(final K key, final V value)
    {
        if (containsKey(key))
        {
            remove(key);
            return true;
        }
        return false;
    }

    @Override
    public V getAndReplace(final K key, final V value)
    {
        if (containsKey(key))
        {
            final V oldValue = get(key);
            put(key, value);
            return oldValue;
        }
        return null;
    }

    @Override
    public void removeAll(final Set<? extends K> keys)
    {
        remove.addAll(keys);
        for (final K k : keys)
        {
            put.remove(k);
        }
    }

    @Override
    public void removeAll()
    {
        removeAll = true;
        put.clear();
        remove.clear();
    }

    @Override
    public void clear()
    {
        clear = true;
        put.clear();
        remove.clear();
    }

    @Override
    public <C extends Configuration<K, V>> C getConfiguration(final Class<C> clazz)
    {
        return cache.getConfiguration(clazz);
    }

    @Override
    public <T> T invoke(final K key, final EntryProcessor<K, V, T> entryProcessor, final Object... arguments) throws EntryProcessorException
    {
        return cache.invoke(key, entryProcessor, arguments);
    }

    @Override
    public <T> Map<K, EntryProcessorResult<T>> invokeAll(final Set<? extends K> keys, final EntryProcessor<K, V, T> entryProcessor,
            final Object... arguments)
    {
        return cache.invokeAll(keys, entryProcessor, arguments);
    }

    @Override
    public String getName()
    {
        return cache.getName();
    }

    @Override
    public CacheManager getCacheManager()
    {
        return cache.getCacheManager();
    }

    @Override
    public void close()
    {
        cache.close();
    }

    @Override
    public boolean isClosed()
    {
        return cache.isClosed();
    }

    @Override
    public <T> T unwrap(final Class<T> clazz)
    {
        return cache.unwrap(clazz);
    }

    @Override
    public void registerCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
    {
        cache.registerCacheEntryListener(cacheEntryListenerConfiguration);
    }

    @Override
    public void deregisterCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
    {
        cache.deregisterCacheEntryListener(cacheEntryListenerConfiguration);
    }

    @Override
    public Iterator<Entry<K, V>> iterator()
    {
        return cache.iterator();
    }

    public void merge()
    {
        if (removeAll)
        {
            cache.removeAll();
        }
        if (clear)
        {
            cache.clear();
        }

        for (final Map.Entry<K, V> entry : put.entrySet())
        {
            cache.put(entry.getKey(), entry.getValue());
        }
        put.clear();
        for (final K entry : remove)
        {
            cache.remove(entry);
        }
        remove.clear();
    }
}
