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

import static com.google.common.collect.Iterables.transform;
import static org.apache.jackrabbit.oak.plugins.document.Collection.CLUSTER_NODES;
import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;

import com.mongodb.BasicDBObject;
import com.mongodb.ReadPreference;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;

import org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo;
import org.apache.jackrabbit.oak.plugins.document.MissingLastRevSeeker;
import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
import org.apache.jackrabbit.oak.plugins.document.util.CloseableIterable;
import org.apache.jackrabbit.oak.stats.Clock;
import org.bson.conversions.Bson;
import org.jetbrains.annotations.NotNull;

/**
 * Mongo specific version of MissingLastRevSeeker which uses mongo queries
 * to fetch candidates which may have missed '_lastRev' updates.
 * 
 * Uses a time range to find documents modified during that interval.
 */
public class MongoMissingLastRevSeeker extends MissingLastRevSeeker {
    private final MongoDocumentStore store;

    public MongoMissingLastRevSeeker(MongoDocumentStore store, Clock clock) {
        super(store, clock);
        this.store = store;
    }

    @Override
    @NotNull
    public CloseableIterable<NodeDocument> getCandidates(final long startTime) {
        Bson query = Filters.and(
                Filters.gte(NodeDocument.MODIFIED_IN_SECS, NodeDocument.getModifiedInSecs(startTime)),
                Filters.exists(NodeDocument.SD_TYPE, false));
        Bson sortFields = new BasicDBObject(NodeDocument.MODIFIED_IN_SECS, 1);

        FindIterable<BasicDBObject> cursor = getNodeCollection()
                .find(query).sort(sortFields);
        return CloseableIterable.wrap(transform(cursor,
                input -> store.convertFromDBObject(NODES, input)));
    }

    @Override
    public boolean isRecoveryNeeded() {
        Bson query = Filters.and(
                Filters.eq(ClusterNodeInfo.STATE, ClusterNodeInfo.ClusterNodeState.ACTIVE.name()),
                Filters.or(
                        Filters.lt(ClusterNodeInfo.LEASE_END_KEY, clock.getTime()),
                        Filters.eq(ClusterNodeInfo.REV_RECOVERY_LOCK, ClusterNodeInfo.RecoverLockState.ACQUIRED.name())
                )
        );

        return getClusterNodeCollection().find(query).iterator().hasNext();
    }

    private MongoCollection<BasicDBObject> getNodeCollection() {
        return store.getDBCollection(NODES, ReadPreference.primary());
    }

    private MongoCollection<BasicDBObject> getClusterNodeCollection() {
        return store.getDBCollection(CLUSTER_NODES, ReadPreference.primary());
    }
}

