/*
 * 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.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.binary.BinaryBasicIdMapper;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.BinaryConfiguration;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
import org.apache.ignite.internal.util.future.IgniteFinishedFutureImpl;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.spi.discovery.DiscoveryNotification;
import org.apache.ignite.spi.discovery.DiscoverySpiListener;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;

import static org.apache.ignite.cache.CacheMode.REPLICATED;
import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;

/**
 * Tests situation when two nodes in cluster simultaneously propose different classes with the same typeId
 * (which is actually class name's <b>hashCode</b> ).
 *
 * In that case one of the propose requests should be rejected
 * and {@link org.apache.ignite.internal.processors.marshaller.MappingProposedMessage} is sent
 * with not-null <b>conflictingClsName</b> field.
 */
public class IgniteMarshallerCacheClassNameConflictTest extends GridCommonAbstractTest {
    /** */
    private volatile boolean bbClsRejected;

    /** */
    private volatile boolean aaClsRejected;

    /** */
    private volatile boolean rejectObserved;

    /**
     * Latch used to synchronize two nodes on sending mapping requests for classes with conflicting names.
     */
    private static final CountDownLatch startLatch = new CountDownLatch(3);

    /** */
    private static volatile boolean busySpinFlag;

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

        TcpDiscoverySpi disco = new TestTcpDiscoverySpi();
        disco.setIpFinder(LOCAL_IP_FINDER);

        cfg.setDiscoverySpi(disco);

        CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME);

        ccfg.setCacheMode(REPLICATED);
        ccfg.setRebalanceMode(SYNC);
        ccfg.setWriteSynchronizationMode(FULL_SYNC);

        cfg.setCacheConfiguration(ccfg);

        // Use case sensitive mapper
        BinaryConfiguration binaryCfg = new BinaryConfiguration().setIdMapper(new BinaryBasicIdMapper(false));

        cfg.setBinaryConfiguration(binaryCfg);

        return cfg;
    }

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

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testCachePutGetClassesWithNameConflict() throws Exception {
        Ignite srv1 = startGrid(0);
        Ignite srv2 = startGrid(1);
        ExecutorService exec1 = srv1.executorService();
        ExecutorService exec2 = srv2.executorService();

        final AtomicInteger trickCompilerVar = new AtomicInteger(1);

        // "Aa" and "BB" have same hash code
        final Aa aOrg1 = new Aa(1, "Microsoft", "One Microsoft Way Redmond, WA 98052-6399, USA");
        final BB bOrg2 = new BB(2, "Apple", "1 Infinite Loop, Cupertino, CA 95014, USA");

        exec1.submit(new Runnable() {
            @Override public void run() {
                startLatch.countDown();

                try {
                    startLatch.await();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //busy spinning after waking up from startLatch.await
                // to reduce probability that one thread starts significantly earlier than the other
                while (!busySpinFlag) {
                    if (trickCompilerVar.get() < 0)
                        break;
                }

                Ignition.localIgnite().cache(DEFAULT_CACHE_NAME).put(1, aOrg1);
            }
        });

        exec2.submit(new Runnable() {
            @Override public void run() {
                startLatch.countDown();

                try {
                    startLatch.await();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //busy spinning after waking up from startLatch.await
                // to reduce probability that one thread starts significantly earlier than the other
                while (!busySpinFlag) {
                    if (trickCompilerVar.get() < 0)
                        break;
                }

                Ignition.localIgnite().cache(DEFAULT_CACHE_NAME).put(2, bOrg2);
            }
        });
        startLatch.countDown();

        busySpinFlag = true;

        exec1.shutdown();
        exec2.shutdown();

        exec1.awaitTermination(100, TimeUnit.MILLISECONDS);
        exec2.awaitTermination(100, TimeUnit.MILLISECONDS);

        Ignite ignite = startGrid(2);

        int cacheSize = ignite.cache(DEFAULT_CACHE_NAME).size(CachePeekMode.PRIMARY);

        assertTrue("Expected cache size 1 but was " + cacheSize, cacheSize == 1);

        if (rejectObserved)
            assertTrue(aaClsRejected || bbClsRejected);
    }

    /** */
    private class TestTcpDiscoverySpi extends TcpDiscoverySpi {

        /** */
        private class DiscoverySpiListenerWrapper implements DiscoverySpiListener {
            /** */
            private DiscoverySpiListener delegate;

            /**
             * @param delegate Delegate.
             */
            private DiscoverySpiListenerWrapper(DiscoverySpiListener delegate) {
                this.delegate = delegate;
            }

            /** {@inheritDoc} */
            @Override public IgniteFuture<?> onDiscovery(
                DiscoveryNotification notification
            ) {
                DiscoveryCustomMessage customMsg = notification.getCustomMsgData() == null ? null
                        : (DiscoveryCustomMessage)U.field(notification.getCustomMsgData(), "delegate");

                if (customMsg != null) {
                    //don't want to make this class public, using equality of class name instead of instanceof operator
                    if ("MappingProposedMessage".equals(customMsg.getClass().getSimpleName())) {
                        String conflClsName = U.field(customMsg, "conflictingClsName");
                        if (conflClsName != null && !conflClsName.isEmpty()) {
                            rejectObserved = true;
                            if (conflClsName.contains(Aa.class.getSimpleName()))
                                bbClsRejected = true;
                            else if (conflClsName.contains(BB.class.getSimpleName()))
                                aaClsRejected = true;
                        }
                    }
                }

                if (delegate != null)
                    return delegate.onDiscovery(notification);

                return new IgniteFinishedFutureImpl<>();
            }

            /** {@inheritDoc} */
            @Override public void onLocalNodeInitialized(ClusterNode locNode) {
                // No-op.
            }
        }

        /** {@inheritDoc} */
        @Override public void setListener(@Nullable DiscoverySpiListener lsnr) {
            super.setListener(new DiscoverySpiListenerWrapper(lsnr));
        }
    }

}

/**
 * Class name is chosen to be in conflict with other class name this test put to cache.
 */
class Aa {
    /** */
    private final int id;

    /** */
    private final String name;

    /** */
    private final String addr;

    /**
     * @param id Id.
     * @param name Name.
     * @param addr Address.
     */
    Aa(int id, String name, String addr) {
        this.id = id;
        this.name = name;
        this.addr = addr;
    }
}

/**
 * Class name is chosen to be in conflict with other class name this test put to cache.
 */
class BB {
    /** */
    private final int id;

    /** */
    private final String name;

    /** */
    private final String addr;

    /**
     * @param id Id.
     * @param name Name.
     * @param addr Address.
     */
    BB(int id, String name, String addr) {
        this.id = id;
        this.name = name;
        this.addr = addr;
    }
}
