/*
 * 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.jackrabbit.oak.plugins.document.util;

import java.util.List;
import java.util.Map;

import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo;
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
import org.apache.jackrabbit.oak.plugins.document.DocumentStore;
import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
import org.apache.jackrabbit.oak.plugins.document.UpdateOp;
import org.apache.jackrabbit.oak.plugins.document.cache.CacheInvalidationStats;
import org.jetbrains.annotations.NotNull;

/**
 * Wrapper of another DocumentStore that does a lease check on any method
 * invocation (read or update) and fails if the lease is not valid.
 * <p>
 * @see "https://issues.apache.org/jira/browse/OAK-2739 for more details"
 */
public final class LeaseCheckDocumentStoreWrapper implements DocumentStore {

    private final DocumentStore delegate;
    private final ClusterNodeInfo clusterNodeInfo;

    public LeaseCheckDocumentStoreWrapper(final DocumentStore delegate, final ClusterNodeInfo clusterNodeInfo) {
        if (delegate == null) {
            throw new IllegalArgumentException("delegate must not be null");
        }
        this.delegate = delegate;
        // clusterNodeInfo is allowed to be null - eg for testing
        this.clusterNodeInfo = clusterNodeInfo;
    }

    private final void performLeaseCheck() {
        if (clusterNodeInfo != null) {
            clusterNodeInfo.performLeaseCheck();
        }
    }

    @Override
    public final <T extends Document> T find(Collection<T> collection, String key) {
        performLeaseCheck();
        return delegate.find(collection, key);
    }

    @Override
    public final <T extends Document> T find(Collection<T> collection, String key,
            int maxCacheAge) {
        performLeaseCheck();
        return delegate.find(collection, key, maxCacheAge);
    }

    @Override
    public final <T extends Document> List<T> query(Collection<T> collection,
            String fromKey, String toKey, int limit) {
        performLeaseCheck();
        return delegate.query(collection, fromKey, toKey, limit);
    }

    @Override
    public final <T extends Document> List<T> query(Collection<T> collection,
            String fromKey, String toKey, String indexedProperty,
            long startValue, int limit) {
        performLeaseCheck();
        return delegate.query(collection, fromKey, toKey, indexedProperty, startValue, limit);
    }

    @Override
    public final <T extends Document> void remove(Collection<T> collection, String key) {
        performLeaseCheck();
        delegate.remove(collection, key);
    }

    @Override
    public final <T extends Document> void remove(Collection<T> collection,
            List<String> keys) {
        performLeaseCheck();
        delegate.remove(collection, keys);
    }

    @Override
    public final <T extends Document> int remove(Collection<T> collection,
            Map<String, Long> toRemove) {
        performLeaseCheck();
        return delegate.remove(collection, toRemove);
    }

    @Override
    public<T extends Document> int remove(Collection<T> collection,
                                          String indexedProperty, long startValue, long endValue)
            throws DocumentStoreException {
        performLeaseCheck();
        return delegate.remove(collection, indexedProperty, startValue, endValue);
    }

    @Override
    public final <T extends Document> boolean create(Collection<T> collection,
            List<UpdateOp> updateOps) {
        performLeaseCheck();
        return delegate.create(collection, updateOps);
    }

    @Override
    public final <T extends Document> T createOrUpdate(Collection<T> collection,
            UpdateOp update) {
        performLeaseCheck();
        return delegate.createOrUpdate(collection, update);
    }

    @Override
    public <T extends Document> List<T> createOrUpdate(Collection<T> collection,
            List<UpdateOp> updateOps) {
        performLeaseCheck();
        return delegate.createOrUpdate(collection, updateOps);
    }

    @Override
    public final <T extends Document> T findAndUpdate(Collection<T> collection,
            UpdateOp update) {
        performLeaseCheck();
        return delegate.findAndUpdate(collection, update);
    }

    @Override
    public final CacheInvalidationStats invalidateCache() {
        performLeaseCheck();
        return delegate.invalidateCache();
    }

    @Override
    public final CacheInvalidationStats invalidateCache(Iterable<String> keys) {
        performLeaseCheck();
        return delegate.invalidateCache(keys);
    }

    @Override
    public final <T extends Document> void invalidateCache(Collection<T> collection,
            String key) {
        performLeaseCheck();
        delegate.invalidateCache(collection, key);
    }

    @Override
    public final void dispose() {
        // this is debatable whether or not a lease check should be done on dispose.
        // I'd say the lease must still be valid as on dispose there could be
        // stuff written to the document store which should only be done
        // when the lease is valid.
        // however.. dispose() is also called as a result of the 'failed lease check stopping'
        // mechanism - and in that case this would just throw an exception and the
        // DocumentNodeStore.dispose() would not correctly finish.
        // so: let's let the dispose ignore the lease state
        delegate.dispose();
    }

    @Override
    public final <T extends Document> T getIfCached(Collection<T> collection,
            String key) {
        performLeaseCheck();
        return delegate.getIfCached(collection, key);
    }

    @Override
    public final void setReadWriteMode(String readWriteMode) {
        performLeaseCheck();
        delegate.setReadWriteMode(readWriteMode);
    }

    @Override
    public final Iterable<CacheStats> getCacheStats() {
        performLeaseCheck();
        return delegate.getCacheStats();
    }

    @Override
    public final Map<String, String> getMetadata() {
        performLeaseCheck();
        return delegate.getMetadata();
    }

    @NotNull
    @Override
    public Map<String, String> getStats() {
        performLeaseCheck();
        return delegate.getStats();
    }

    @Override
    public long determineServerTimeDifferenceMillis() {
        performLeaseCheck();
        return delegate.determineServerTimeDifferenceMillis();
    }
}
