/*
 * 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.cassandra.net;

import java.util.Random;

import org.junit.Test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.net.PrunableArrayQueue;

import static org.junit.Assert.*;

public class PrunableArrayQueueTest
{
    private static final Logger logger = LoggerFactory.getLogger(PrunableArrayQueueTest.class);

    private final PrunableArrayQueue<Integer> queue = new PrunableArrayQueue<>(8);

    @Test
    public void testIsEmptyWhenEmpty()
    {
        assertTrue(queue.isEmpty());
    }

    @Test
    public void testIsEmptyWhenNotEmpty()
    {
        queue.offer(0);
        assertFalse(queue.isEmpty());
    }

    @Test
    public void testEmptyPeek()
    {
        assertNull(queue.peek());
    }

    @Test
    public void testNonEmptyPeek()
    {
        queue.offer(0);
        assertEquals((Integer) 0, queue.peek());
    }

    @Test
    public void testEmptyPoll()
    {
        assertNull(queue.poll());
    }

    @Test
    public void testNonEmptyPoll()
    {
        queue.offer(0);
        assertEquals((Integer) 0, queue.poll());
    }

    @Test
    public void testTransfersInCorrectOrder()
    {
        for (int i = 0; i < 1024; i++)
            queue.offer(i);

        for (int i = 0; i < 1024; i++)
            assertEquals((Integer) i, queue.poll());

        assertTrue(queue.isEmpty());
    }

    @Test
    public void testTransfersInCorrectOrderWhenInterleaved()
    {
        for (int i = 0; i < 1024; i++)
        {
            queue.offer(i);
            assertEquals((Integer) i, queue.poll());
        }

        assertTrue(queue.isEmpty());
    }

    @Test
    public void testPrune()
    {
        for (int i = 0; i < 1024; i++)
            queue.offer(i);

        class Pruner implements PrunableArrayQueue.Pruner<Integer>
        {
            private int pruned, kept;

            public boolean shouldPrune(Integer val)
            {
                return val % 2 == 0;
            }

            public void onPruned(Integer val)
            {
                pruned++;
            }

            public void onKept(Integer val)
            {
                kept++;
            }
        }

        Pruner pruner = new Pruner();
        assertEquals(512, queue.prune(pruner));

        assertEquals(512, pruner.kept);
        assertEquals(512, pruner.pruned);
        assertEquals(512, queue.size());

        for (int i = 1; i < 1024; i += 2)
            assertEquals((Integer) i, queue.poll());
        assertTrue(queue.isEmpty());
    }

    @Test
    public void testUnreliablePruner()
    {
        long seed = System.currentTimeMillis();
        Random rand = new Random(seed);

        logger.info("Testing unreliable pruner with random seed {}...", seed);

        int iteratons = 100;
        int startingQueueSize = 1024;
        double pruneChance = 0.1;
        double errorOnKeptChance = 0.00005;
        double errorOnPruneChance = 0.00002;

        for (int i = 0; i < iteratons; i++)
        {
            int failureValue = rand.nextInt(startingQueueSize);

            PrunableArrayQueue<Integer> testQueue = new PrunableArrayQueue<>(startingQueueSize);

            for (int o = 0; o < startingQueueSize; o++)
                testQueue.offer(o);

            class UnreliablePruner implements PrunableArrayQueue.Pruner<Integer>
            {
                public boolean shouldPrune(Integer value)
                {
                    if (rand.nextDouble() < errorOnPruneChance)
                        throw new RuntimeException("Failed on pruning check for value: " + value);

                    return rand.nextDouble() < pruneChance;
                }

                public void onPruned(Integer value)
                {
                    if (value == failureValue)
                        throw new RuntimeException("Failed on pruned value: " + value);
                }

                public void onKept(Integer value)
                {
                    if (rand.nextDouble() < errorOnKeptChance)
                        throw new RuntimeException("Failed on retained value: " + value);
                }
            }

            assertEquals(startingQueueSize, testQueue.size());

            try
            {
                testQueue.prune(new UnreliablePruner());
            }
            catch (RuntimeException e)
            {
                logger.info("Expected pruning failure with seed {}", seed, e);
            }

            for (int p = 0, postPruneSize = testQueue.size(); p < postPruneSize; p++)
            {
                assertNotNull("Queue should contain no null elements after pruning. Seed: " + seed + ". Iteration: " + i, testQueue.poll());
            }

            assertEquals("Queue size should be zero after draining. Seed: " + seed + ". Iteration: " + i, 0, testQueue.size());
        }
    }
}