/*
 * 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.openjpa.persistence;

import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;

import org.apache.openjpa.datacache.CacheStatistics;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.datacache.DelegatingDataCache;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;

/**
 * Implements the L2 cache over the data store via delegation to DataCache.
 *
 * @author Abe White
 * @since 0.4.1
 */
public class StoreCacheImpl
	implements StoreCache {

    private final MetaDataRepository _repos;
    private final DelegatingDataCache _cache;


    /**
     * Constructor; supply delegate.
     */
    public StoreCacheImpl(EntityManagerFactoryImpl emf, DataCache cache) {
        _repos = emf.getConfiguration().getMetaDataRepositoryInstance();
        _cache = new DelegatingDataCache(cache,
            PersistenceExceptions.TRANSLATOR);
    }

    /**
     * Delegate.
     */
    @Override
    public DataCache getDelegate() {
        return _cache.getDelegate();
    }

    @Override
    public boolean contains(Class cls, Object oid) {
        return _cache.getDelegate() != null && _cache.contains
            (JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls), oid));
    }

    @Override
    public boolean containsAll(Class cls, Object... oids) {
        return containsAll(cls, Arrays.asList(oids));
    }

    @Override
    public boolean containsAll(Class cls, Collection oids) {
        if (_cache.getDelegate() == null)
            return oids.isEmpty();

        BitSet set = _cache.containsAll(JPAFacadeHelper.toOpenJPAObjectIds
            (getMetaData(cls), oids));
        for (int i = 0; i < oids.size(); i++)
            if (!set.get(i))
                return false;
        return true;
    }

    @Override
    public void pin(Class cls, Object oid) {
        if (_cache.getDelegate() != null)
            _cache.pin(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls),
                oid));
    }

    @Override
    public void pinAll(Class cls, Object... oids) {
        pinAll(cls, Arrays.asList(oids));
    }

    @Override
    public void pinAll(Class cls, Collection oids) {
        if (_cache.getDelegate() != null)
            _cache.pinAll(JPAFacadeHelper.toOpenJPAObjectIds
                (getMetaData(cls), oids));
    }

    @Override
    public void unpin(Class cls, Object oid) {
        if (_cache.getDelegate() != null)
            _cache.unpin(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls),
                oid));
    }

    @Override
    public void unpinAll(Class cls, Object... oids) {
        unpinAll(cls, Arrays.asList(oids));
    }

    @Override
    public void unpinAll(Class cls, Collection oids) {
        if (_cache.getDelegate() != null)
            _cache.unpinAll(JPAFacadeHelper.toOpenJPAObjectIds
                (getMetaData(cls), oids));
    }

    @Override
    public void evict(Class cls, Object oid) {
        if (_cache.getDelegate() != null)
            _cache.remove(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls),
                oid));
    }

    @Override
    public void evictAll(Class cls, Object... oids) {
        evictAll(cls, Arrays.asList(oids));
    }

    @Override
    public void evictAll(Class cls, Collection oids) {
        if (_cache.getDelegate() != null)
            _cache.removeAll(JPAFacadeHelper.toOpenJPAObjectIds
                (getMetaData(cls), oids));
    }

    @Override
    public void evictAll() {
        _cache.clear();
    }

    @Override
    public <T> T unwrap(Class<T> cls) {
        if (cls.isInstance(this)) {
            return cls.cast(this);
        }
        throw new javax.persistence.PersistenceException(cls.getName() + " not supported");
    }

    @Override
    public CacheStatistics getStatistics() {
    	return (_cache == null) ? null : _cache.getStatistics();
    }

    /**
     * Return metadata for the given class, throwing the proper exception
     * if not persistent.
     */
    private ClassMetaData getMetaData(Class cls) {
        try {
            return _repos.getMetaData(cls, null, true);
        } catch (RuntimeException re) {
            throw PersistenceExceptions.toPersistenceException(re);
        }
    }

    @Override
    public int hashCode() {
        return (_cache == null) ? 0 : _cache.hashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this)
            return true;
        if ((other == null) || (other.getClass() != this.getClass()))
            return false;
        if (_cache == null)
            return false;
      return _cache.equals (((StoreCacheImpl) other)._cache);
	}

    @Override
    @SuppressWarnings("unchecked")
    public void evict(Class cls) {
        // Check MetaData throws a consistent exception with evict(Class,
        // Object)
        if(getMetaData(cls) != null) {
            _cache.removeAll(cls, true);
        }
    }
}
