/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed 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.utils;

import junit.framework.TestCase;

import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Unit test for {@code AbstractIterator}.
 *
 * @author Kevin Bourrillion
 */
@SuppressWarnings("serial") // No serialization is used in this test
// TODO(cpovirk): why is this slow (>1m/test) under GWT when fully optimized?
public class AbstractIteratorTest extends TestCase
{

    public void testDefaultBehaviorOfNextAndHasNext()
    {

        // This sample AbstractIterator returns 0 on the first call, 1 on the
        // second, then signals that it's reached the end of the data
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            private int rep;

            @Override
            public Integer computeNext()
            {
                switch (rep++)
                {
                    case 0:
                        return 0;
                    case 1:
                        return 1;
                    case 2:
                        return endOfData();
                    default:
                        fail("Should not have been invoked again");
                        return null;
                }
            }
        };

        assertTrue(iter.hasNext());
        assertEquals(0, (int) iter.next());

        // verify idempotence of hasNext()
        assertTrue(iter.hasNext());
        assertTrue(iter.hasNext());
        assertTrue(iter.hasNext());
        assertEquals(1, (int) iter.next());

        assertFalse(iter.hasNext());

        // Make sure computeNext() doesn't get invoked again
        assertFalse(iter.hasNext());

        try
        {
            iter.next();
            fail("no exception thrown");
        }
        catch (NoSuchElementException expected)
        {
        }
    }

    public void testDefaultBehaviorOfPeek()
    {
    /*
     * This sample AbstractIterator returns 0 on the first call, 1 on the
     * second, then signals that it's reached the end of the data
     */
        AbstractIterator<Integer> iter = new AbstractIterator<Integer>()
        {
            private int rep;

            @Override
            public Integer computeNext()
            {
                switch (rep++)
                {
                    case 0:
                        return 0;
                    case 1:
                        return 1;
                    case 2:
                        return endOfData();
                    default:
                        fail("Should not have been invoked again");
                        return null;
                }
            }
        };

        assertEquals(0, (int) iter.peek());
        assertEquals(0, (int) iter.peek());
        assertTrue(iter.hasNext());
        assertEquals(0, (int) iter.peek());
        assertEquals(0, (int) iter.next());

        assertEquals(1, (int) iter.peek());
        assertEquals(1, (int) iter.next());

        try
        {
            iter.peek();
            fail("peek() should throw NoSuchElementException at end");
        }
        catch (NoSuchElementException expected)
        {
        }

        try
        {
            iter.peek();
            fail("peek() should continue to throw NoSuchElementException at end");
        }
        catch (NoSuchElementException expected)
        {
        }

        try
        {
            iter.next();
            fail("next() should throw NoSuchElementException as usual");
        }
        catch (NoSuchElementException expected)
        {
        }

        try
        {
            iter.peek();
            fail("peek() should still throw NoSuchElementException after next()");
        }
        catch (NoSuchElementException expected)
        {
        }
    }

    public void testFreesNextReference() throws InterruptedException
    {
        Iterator<Object> itr = new AbstractIterator<Object>()
        {
            @Override
            public Object computeNext()
            {
                return new Object();
            }
        };
        WeakReference<Object> ref = new WeakReference<Object>(itr.next());
        while (ref.get() != null)
        {
            System.gc();
            Thread.sleep(1);
        }
    }

    public void testDefaultBehaviorOfPeekForEmptyIteration()
    {

        AbstractIterator<Integer> empty = new AbstractIterator<Integer>()
        {
            private boolean alreadyCalledEndOfData;

            @Override
            public Integer computeNext()
            {
                if (alreadyCalledEndOfData)
                {
                    fail("Should not have been invoked again");
                }
                alreadyCalledEndOfData = true;
                return endOfData();
            }
        };

        try
        {
            empty.peek();
            fail("peek() should throw NoSuchElementException at end");
        }
        catch (NoSuchElementException expected)
        {
        }

        try
        {
            empty.peek();
            fail("peek() should continue to throw NoSuchElementException at end");
        }
        catch (NoSuchElementException expected)
        {
        }
    }

    public void testException()
    {
        final SomeUncheckedException exception = new SomeUncheckedException();
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            @Override
            public Integer computeNext()
            {
                throw exception;
            }
        };

        // It should pass through untouched
        try
        {
            iter.hasNext();
            fail("No exception thrown");
        }
        catch (SomeUncheckedException e)
        {
            assertSame(exception, e);
        }
    }

    public void testExceptionAfterEndOfData()
    {
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            @Override
            public Integer computeNext()
            {
                endOfData();
                throw new SomeUncheckedException();
            }
        };
        try
        {
            iter.hasNext();
            fail("No exception thrown");
        }
        catch (SomeUncheckedException expected)
        {
        }
    }

    public void testCantRemove()
    {
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            boolean haveBeenCalled;

            @Override
            public Integer computeNext()
            {
                if (haveBeenCalled)
                {
                    endOfData();
                }
                haveBeenCalled = true;
                return 0;
            }
        };

        assertEquals(0, (int) iter.next());

        try
        {
            iter.remove();
            fail("No exception thrown");
        }
        catch (UnsupportedOperationException expected)
        {
        }
    }

    public void testSneakyThrow() throws Exception
    {
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            boolean haveBeenCalled;

            @Override
            public Integer computeNext()
            {
                if (haveBeenCalled)
                {
                    fail("Should not have been called again");
                }
                else
                {
                    haveBeenCalled = true;
                    sneakyThrow(new SomeCheckedException());
                }
                return null; // never reached
            }
        };

        // The first time, the sneakily-thrown exception comes out
        try
        {
            iter.hasNext();
            fail("No exception thrown");
        }
        catch (Exception e)
        {
            if (!(e instanceof SomeCheckedException))
            {
                throw e;
            }
        }

        // But the second time, AbstractIterator itself throws an ISE
        try
        {
            iter.hasNext();
            fail("No exception thrown");
        }
        catch (IllegalStateException expected)
        {
        }
    }

    public void testReentrantHasNext()
    {
        Iterator<Integer> iter = new AbstractIterator<Integer>()
        {
            @Override
            protected Integer computeNext()
            {
                hasNext();
                return null;
            }
        };
        try
        {
            iter.hasNext();
            fail();
        }
        catch (IllegalStateException expected)
        {
        }
    }

    /**
     * Throws a undeclared checked exception.
     */
    private static void sneakyThrow(Throwable t)
    {
        class SneakyThrower<T extends Throwable>
        {
            @SuppressWarnings("unchecked")
                // not really safe, but that's the point
            void throwIt(Throwable t) throws T
            {
                throw (T) t;
            }
        }
        new SneakyThrower<Error>().throwIt(t);
    }

    private static class SomeCheckedException extends Exception
    {
    }

    private static class SomeUncheckedException extends RuntimeException
    {
    }
}