/*
 * 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.ignite.internal.processors.cache;

import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.cache.CacheException;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cluster.ClusterTopologyException;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.util.typedef.CAX;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.MvccFeatureChecker;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionRollbackException;
import org.junit.Assume;
import org.junit.Test;

import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;

/**
 * Affinity routing tests.
 */
public class GridCacheVariableTopologySelfTest extends GridCommonAbstractTest {
    /** */
    private static final Random RAND = new Random();

    /** {@inheritDoc} */
    @Override protected void beforeTest() throws Exception {
        Assume.assumeFalse("https://issues.apache.org/jira/browse/IGNITE-7388", MvccFeatureChecker.forcedMvcc());

        super.beforeTest();
    }

    /** Constructs test. */
    public GridCacheVariableTopologySelfTest() {
        super(/* don't start grid */ false);
    }

    /** {@inheritDoc} */
    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);

        // Default cache configuration.
        CacheConfiguration cacheCfg = defaultCacheConfiguration();

        cacheCfg.setCacheMode(PARTITIONED);
        cacheCfg.setBackups(1);
        cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
        cacheCfg.setAtomicityMode(TRANSACTIONAL);

        cfg.setCacheConfiguration(cacheCfg);

        return cfg;
    }

    /** {@inheritDoc} */
    @Override protected void afterTest() throws Exception {
        super.afterTest();

        stopAllGrids();

        assert G.allGrids().isEmpty();
    }

    /**
     * @param cnt Number of grids to starts.
     * @param startIdx Start grid index.
     * @throws Exception If failed to start grids.
     */
    private void startGrids(int cnt, int startIdx) throws Exception {
        assert startIdx >= 0;
        assert cnt >= 0;

        for (int idx = startIdx; idx < startIdx + cnt; idx++)
            startGrid(idx);
    }

    /**
     * JUnit.
     *
     * @throws Exception If failed.
     */
    @SuppressWarnings({"TooBroadScope"})
    @Test
    public void testNodeStop() throws Exception {
        // -- Test parameters. -- //
        int nodeCnt = 3;
        int threadCnt = 20;
        final int txCnt = 1000;
        final long txDelay = 0;
        final int keyRange = 1000;
        final int logMod = 20;

        assert nodeCnt > 1 : "Node count for this test must be greater than 1.";

        startGrids(nodeCnt, 0);

        final AtomicBoolean done = new AtomicBoolean();

        IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync(new CAX() {
            /** */
            private int cnt;

            @SuppressWarnings({"BusyWait"})
            @Override public void applyx() {
                while (cnt++ < txCnt && !done.get()) {
                    IgniteCache<Object, Object> cache = grid(0).cache(DEFAULT_CACHE_NAME);

                    if (cnt % logMod == 0)
                        info("Starting transaction: " + cnt);

                    try (Transaction tx = grid(0).transactions().txStart()) {
                        int kv = RAND.nextInt(keyRange);

                        cache.put(kv, kv);

                        cache.get(kv);

                        tx.commit();
                    }
                    catch (TransactionRollbackException | ClusterTopologyException e) {
                        info("Caught exception: " + e);
                    }
                    catch (CacheException | IgniteException e) {
                        if (X.hasCause(e, ClusterTopologyCheckedException.class))
                            info("Caught cache exception: " + e);
                        else
                            throw e;
                    }

                    try {
                        Thread.sleep(txDelay);
                    }
                    catch (InterruptedException ignored) {
                        // No-op.
                    }
                }
            }
        }, threadCnt, "TEST-THREAD");

        Thread.sleep(2000);

        for (int idx = 1; idx < nodeCnt; idx++) {
            info("Stopping node: " + idx);

            stopGrid(idx);
        }

        // This is just for debugging.
        /*
        GridFuture<?> debugFut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
            @SuppressWarnings({"UnusedDeclaration"})
            @Override public void run() {
                Cache<Object, Object> cache = ((IgniteKernal)grid(0)).cache(DEFAULT_CACHE_NAME);

                try {
                    Thread.sleep(15000);
                }
                catch (InterruptedException ignored) {
                    return;
                }

                info("Set breakpoint here.");
            }
        }, 1, "TEST-THREAD");
        */

        done.set(true);

        fut.get();

        stopGrid(0);

        info("Grid 0 stopped.");

        //debugFut.get();
    }
}
