/*
 * 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 java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.UpdateResult;

import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
import org.apache.jackrabbit.oak.plugins.document.NodeDocumentHelper;
import org.apache.jackrabbit.oak.plugins.document.Revision;
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.bson.conversions.Bson;

import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;

/**
 * Helper class to access package private methods on MongoDocumentStore.
 */
public class MongoDocumentStoreHelper {

    private MongoDocumentStoreHelper() {
    }

    public static void repair(MongoDocumentStore store, String path) {
        MongoCollection<BasicDBObject> col = store.getDBCollection(NODES);
        String id = Utils.getIdFromPath(path);

        NodeDocument doc = store.find(NODES, id);
        if (doc == null) {
            System.out.println("No document for path " + path);
            return;
        }
        
        Set<Revision> changes = Sets.newHashSet();
        for (String key : doc.keySet()) {
            if (Utils.isPropertyName(key) || NodeDocument.isDeletedEntry(key)) {
                changes.addAll(NodeDocumentHelper.getLocalMap(doc, key).keySet());
            }
        }

        SortedMap<Revision, String> commitRoot = Maps
            .newTreeMap(NodeDocumentHelper.getLocalCommitRoot(doc));
        if (!commitRoot.keySet().retainAll(changes)) {
            System.out.println("Nothing to repair on " + path);
            return;
        }
        
        Number modCount = doc.getModCount();
        if (modCount == null) {
            System.err.println("Document does not have a modCount " + path);
            return;
        }
        Bson query = Filters.and(
                Filters.eq(Document.ID, id),
                Filters.eq(Document.MOD_COUNT, modCount)
        );
        DBObject cr = new BasicDBObject();
        for (Map.Entry<Revision, String> entry : commitRoot.entrySet()) {
            cr.put(entry.getKey().toString(), entry.getValue());
        }
        
        BasicDBObject update = new BasicDBObject();
        update.put("$set", new BasicDBObject(NodeDocumentHelper.commitRoot(), cr));
        update.put("$inc", new BasicDBObject(Document.MOD_COUNT, 1L));
                
        UpdateResult result = col.updateOne(query, update);
        if (result.getModifiedCount() == 1) {
            int num = NodeDocumentHelper.getLocalCommitRoot(doc).size() - commitRoot.size();
            System.out.println("Removed " + num + " _commitRoot entries on " + path);
        } else {
            System.out.println("Unable to repair " + path + " (concurrent update).");
        }
        
    }

    public static <T extends Document> MongoCollection<BasicDBObject> getDBCollection(
            MongoDocumentStore store, Collection<T> c) {
        return store.getDBCollection(c);
    }

    public static <T extends Document> T convertFromDBObject(
            MongoDocumentStore store, Collection<T> col, DBObject obj) {
        return store.convertFromDBObject(col, obj);
    }

}
