/*
 * 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 com.mongodb.MongoClient;

import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.document.AbstractMongoConnectionTest;
import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
import org.apache.jackrabbit.oak.plugins.document.LeaseCheckMode;
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ClusterConflictTest extends AbstractMongoConnectionTest {

    private DocumentNodeStore ns2;

    @Override
    public void setUpConnection() throws Exception {
        super.setUpConnection();
        MongoConnection connection = connectionFactory.getConnection();
        ns2 = newBuilder(connection.getMongoClient(), connection.getDBName())
                .setClusterId(2).getNodeStore();
    }

    @Override
    protected DocumentMK.Builder newBuilder(MongoClient client, String dbName) throws Exception {
        return super.newBuilder(client, dbName).setAsyncDelay(0).setLeaseCheckMode(LeaseCheckMode.DISABLED);
    }

    @Override
    public void tearDownConnection() throws Exception {
        ns2.dispose();
        super.tearDownConnection();
    }

    // OAK-3433
    @Test
    public void mergeRetryWhileBackgroundRead() throws Exception {
        DocumentNodeStore ns1 = mk.getNodeStore();
        NodeBuilder b1 = ns1.getRoot().builder();
        b1.child("a").child("b").child("c").child("foo");
        merge(ns1, b1);
        ns1.runBackgroundOperations();
        ns2.runBackgroundOperations();

        NodeBuilder b2 = ns2.getRoot().builder();
        // force cache fill
        assertNodeExists(b2, "/a/b/c/foo");

        // remove /a/b/c on ns1
        b1 = ns1.getRoot().builder();
        b1.child("a").child("b").child("c").remove();
        merge(ns1, b1);

        // perform some change on ns2
        b2.child("z");
        merge(ns2, b2);
        runBackgroundUpdate(ns2);

        // this will pickup changes done by ns2 and update
        // the head revision
        runBackgroundRead(ns1);
        // the next step is where the issue described
        // in OAK-3433 occurs.
        // the journal entry with changes done on ns1 is pushed
        // with the current head revision, which is newer
        // than the most recent change in the journal entry
        runBackgroundUpdate(ns1);

        // perform a background read after the rebase
        // the first merge attempt will fail with a conflict
        // because /a/b/c is seen as changed in the future
        // without the fix for OAK-3433:
        // the second merge attempt succeeds because now the
        // /a/b/c change revision is visible and happened before the commit
        // revision but before the base revision
        b2 = ns2.getRoot().builder();
        b2.child("z").setProperty("q", "v");
        try {
            ns2.merge(b2, new CommitHook() {
                @NotNull
                @Override
                public NodeState processCommit(NodeState before,
                                               NodeState after,
                                               CommitInfo info)
                        throws CommitFailedException {
                    runBackgroundRead(ns2);

                    NodeBuilder builder = after.builder();
                    if (builder.getChildNode("a").getChildNode("b").hasChildNode("c")) {
                        builder.child("a").child("b").child("c").child("bar");
                    } else {
                        throw new CommitFailedException(
                                CommitFailedException.OAK, 0,
                                "/a/b/c does not exist anymore");
                    }
                    return builder.getNodeState();
                }
            }, CommitInfo.EMPTY);
            fail("Merge must fail with CommitFailedException");
        } catch (CommitFailedException e) {
            // expected
        }
    }

    private void assertNodeExists(NodeBuilder builder, String path) {
        for (String name : PathUtils.elements(path)) {
            builder = builder.getChildNode(name);
            assertTrue("node '" + name + "' does not exist", builder.exists());
        }
    }

    private static void merge(NodeStore store,
                              NodeBuilder builder) throws Exception {
        store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
    }
}
