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

import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.util.typedef.PA;
import org.apache.ignite.messaging.MessagingListenActor;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;

/**
 * Tests for {@link org.apache.ignite.messaging.MessagingListenActor}.
 */
public class GridListenActorSelfTest extends GridCommonAbstractTest {
    /** */
    private static final int MSG_QTY = 10;

    /** */
    private static final int PING_PONG_STEPS = 10;

    /** {@inheritDoc} */
    @Override protected void beforeTestsStarted() throws Exception {
        startGrid();
    }

    /** {@inheritDoc} */
    @Override protected void afterTest() throws Exception {
        ((IgniteKernal)grid()).context().io().
            removeMessageListener(GridTopic.TOPIC_COMM_USER.name());
    }

    /**
     *
     * @throws Exception Thrown if failed.
     */
    @Test
    public void testBasicFlow() throws Exception {
        final AtomicInteger cnt = new AtomicInteger(0);

        grid().message().localListen(null, new MessagingListenActor<String>() {
            @Override public void receive(UUID uuid, String rcvMsg) {
                if ("TEST".equals(rcvMsg)) {
                    cnt.incrementAndGet();

                    // "Exit" after 1st message.
                    // Should never receive any more messages.
                    stop();
                } else {
                    assert false : "Unknown message: " + rcvMsg;

                    stop();
                }
            }
        });

        grid().message().send(null, "TEST"); // This message we should receive.

        // Flood it.
        for (int i = 0; i < 100; i++)
           grid().message().send(null, "TEST"); // This message should be lost...

        Thread.sleep(2000);

        assert cnt.get() == 1 : "Count is " + cnt.get();
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testImmediateStop() throws Exception {
        doSendReceive(MSG_QTY, 1);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testReceiveAll() throws Exception {
        doSendReceive(MSG_QTY, MSG_QTY);
    }

    /**
     * Testing {@link org.apache.ignite.messaging.MessagingListenActor#respond(UUID, Object)} method.
     *
     * @throws Exception If failed.
     */
    @Test
    public void testRespondToRemote() throws Exception {
        startGrid(1);

        try {
            final ClusterNode rmt = grid(1).localNode();

            grid().message().localListen(null, new MessagingListenActor<String>() {
                @Override protected void receive(UUID nodeId, String rcvMsg) throws IgniteException {
                    System.out.println("Local node received message: '" + rcvMsg + "'");

                    respond(rmt.id(), "RESPONSE");
                }
            });

            final AtomicInteger cnt = new AtomicInteger();

            // Response listener
            grid(1).message().localListen(null, new MessagingListenActor<String>() {
                @Override public void receive(UUID nodeId, String rcvMsg) {
                    if ("RESPONSE".equals(rcvMsg)) {
                        System.out.println("Remote node received message: '" + rcvMsg + "'");

                        cnt.incrementAndGet();
                    }
                }
            });

            grid().message().send(null, "REQUEST");

            assert GridTestUtils.waitForCondition(new PA() {
                @Override public boolean apply() {
                    return cnt.intValue() == 1;
                }
            }, getTestTimeout());
        }
        finally {
            stopGrid(1);
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testPingPong() throws Exception {
        final AtomicInteger pingCnt = new AtomicInteger();
        final AtomicInteger pongCnt = new AtomicInteger();

        final CountDownLatch latch = new CountDownLatch(PING_PONG_STEPS);

        grid().message().localListen(null, new MessagingListenActor<String>() {
            @Override protected void receive(UUID nodeId, String rcvMsg) {
                System.out.println("Received message: '" + rcvMsg + "'");

                if ("PING".equals(rcvMsg)) {
                    pingCnt.incrementAndGet();

                    respond("PONG");
                } else if ("PONG".equals(rcvMsg)) {
                    pongCnt.incrementAndGet();

                    latch.countDown();

                    if (latch.getCount() > 0)
                        respond("PING");
                    else
                        stop();
                }
            }
        });

        grid().message().send(null, "PING");

        latch.await();

        assert pingCnt.intValue() == PING_PONG_STEPS;
        assert pongCnt.intValue() == PING_PONG_STEPS;
    }

    /**
     * @param snd Sent messages quantity.
     * @param rcv Max quantity of received messages before listener is removed.
     * @throws Exception IF failed.
     */
    private void doSendReceive(int snd, final int rcv) throws Exception {
        assert rcv > 0;
        assert snd >= 0;

        final AtomicInteger cnt = new AtomicInteger(0);

        grid().message().localListen(null, new MessagingListenActor<String>() {
            @Override protected void receive(UUID nodeId, String rcvMsg) {
                System.out.println(Thread.currentThread().getName() + "# Received message: '" + rcvMsg + "'");

                cnt.incrementAndGet();

                if (cnt.intValue() == rcv) {
                    System.out.println(Thread.currentThread().getName() + "Calling stop...");

                    stop();
                } else if (cnt.intValue() < rcv)
                    skip();
                else
                    assert false;
            }
        });

        for (int i = 1; i <= snd; i++) {
            String msg = "MESSAGE " + i;

            grid().message().send(null, msg);

            System.out.println(Thread.currentThread().getName() + "# Sent message: '" + msg + "'");
        }

        Thread.sleep(2000);

        assert cnt.intValue() == rcv;
    }
}
