/*
 * 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.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import javax.cache.CacheException;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteClientDisconnectedException;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.processors.datastreamer.DataStreamerResponse;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.testframework.GridTestUtils;
import org.junit.Test;

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

/**
 *
 */
public class IgniteClientReconnectStreamerTest extends IgniteClientReconnectAbstractTest {
    /** */
    public static final String CACHE_NAME = "streamer";

    /** {@inheritDoc} */
    @Override protected int serverCount() {
        return 1;
    }

    /** {@inheritDoc} */
    @Override protected int clientCount() {
        return 1;
    }

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

        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<Integer, Integer>(CACHE_NAME)
            .setAtomicityMode(ATOMIC)
            .setCacheMode(PARTITIONED);

        cfg.setCacheConfiguration(ccfg);

        return cfg;
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testStreamerReconnect() throws Exception {
        final Ignite client = grid(serverCount());

        assertTrue(client.cluster().localNode().isClient());

        Ignite srv = ignite(0);

        final IgniteCache<Object, Object> srvCache = srv.cache(CACHE_NAME);

        IgniteDataStreamer<Integer, Integer> streamer = client.dataStreamer(CACHE_NAME);

        for (int i = 0; i < 50; i++)
            streamer.addData(i, i);

        streamer.flush();

        GridTestUtils.waitForCondition(new GridAbsPredicate() {
            @Override public boolean apply() {
                return srvCache.localSize() == 50;
            }
        }, 2000L);

        assertEquals(50, srvCache.localSize());

        reconnectClientNode(client, srv, new Runnable() {
            @Override public void run() {
                try {
                    client.dataStreamer(CACHE_NAME);

                    fail();
                }
                catch (IgniteClientDisconnectedException e) {
                    assertNotNull(e.reconnectFuture());
                }
            }
        });

        checkStreamerClosed(streamer);

        streamer = client.dataStreamer(CACHE_NAME);

        for (int i = 50; i < 100; i++)
            streamer.addData(i, i);

        streamer.flush();

        GridTestUtils.waitForCondition(new GridAbsPredicate() {
            @Override public boolean apply() {
                return srvCache.localSize() == 100;
            }
        }, 2000L);

        assertEquals(100, srvCache.localSize());

        streamer.close();

        streamer.future().get(2, TimeUnit.SECONDS);

        srvCache.removeAll();
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testStreamerReconnectInProgress() throws Exception {
        Ignite client = grid(serverCount());

        assertTrue(client.cluster().localNode().isClient());

        Ignite srv = ignite(0);

        final IgniteCache<Object, Object> srvCache = srv.cache(CACHE_NAME);

        final IgniteDataStreamer<Integer, Integer> streamer = client.dataStreamer(CACHE_NAME);

        BlockTcpCommunicationSpi commSpi = commSpi(srv);

        commSpi.blockMessage(DataStreamerResponse.class);

        final IgniteInternalFuture<Object> fut = GridTestUtils.runAsync(new Callable<Object>() {
            @Override public Object call() throws Exception {
                try {
                    for (int i = 0; i < 50; i++)
                        streamer.addData(i, i);

                    streamer.flush();
                }
                catch (CacheException e) {
                    checkAndWait(e);

                    return true;
                }
                finally {
                    streamer.close();
                }

                return false;
            }
        });

        // Check that client waiting operation.
        GridTestUtils.assertThrows(log, new Callable<Object>() {
            @Override public Object call() throws Exception {
                return fut.get(200);
            }
        }, IgniteFutureTimeoutCheckedException.class, null);

        assertNotDone(fut);

        commSpi.unblockMessage();

        reconnectClientNode(client, srv, null);

        assertTrue((Boolean)fut.get(2, TimeUnit.SECONDS));

        checkStreamerClosed(streamer);

        IgniteDataStreamer<Integer, Integer> streamer2 = client.dataStreamer(CACHE_NAME);

        for (int i = 0; i < 50; i++)
            streamer2.addData(i, i);

        streamer2.close();

        GridTestUtils.waitForCondition(new GridAbsPredicate() {
            @Override public boolean apply() {
                return srvCache.localSize() == 50;
            }
        }, 2000L);

        assertEquals(50, srvCache.localSize());
    }

    /**
     * @param streamer Streamer.
     */
    private void checkStreamerClosed(IgniteDataStreamer<Integer, Integer> streamer) {
        try {
            streamer.addData(100, 100).get();

            fail();
        }
        catch (CacheException e) {
            checkAndWait(e);
        }

        try {
            streamer.flush();

            fail();
        }
        catch (CacheException e) {
            checkAndWait(e);
        }

        try {
            streamer.future().get();

            fail();
        }
        catch (CacheException e) {
            checkAndWait(e);
        }

        streamer.tryFlush();

        streamer.close();
    }
}
