package org.apache.commons.proxy2.stub;

import org.apache.commons.proxy2.ProxyFactory;
import org.apache.commons.proxy2.cglib.CglibProxyFactory;
import org.apache.commons.proxy2.invoker.NullInvoker;
import org.apache.commons.proxy2.provider.ObjectProviderUtils;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;

import static org.junit.Assert.*;

public abstract class AbstractStubTestCase
{
//----------------------------------------------------------------------------------------------------------------------
// Fields
//----------------------------------------------------------------------------------------------------------------------

    protected ProxyFactory proxyFactory;
    protected StubInterface target;

//----------------------------------------------------------------------------------------------------------------------
// Abstract Methods
//----------------------------------------------------------------------------------------------------------------------

    protected abstract StubInterface createProxy(Trainer<StubInterface> trainer);

//----------------------------------------------------------------------------------------------------------------------
// Other Methods
//----------------------------------------------------------------------------------------------------------------------

    @Before
    public final void setUpProxyFactory()
    {
        this.proxyFactory = new CglibProxyFactory();
        this.target = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE, StubInterface.class);
    }

    @Test
    public void testAnyMatcher()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one(any(String.class))).thenReturn("World");
            }
        });
        assertEquals("World", proxy.one("Hello"));
        assertEquals("World", proxy.one(null));
    }

    @Test(expected = IllegalStateException.class)
    public void testMixingArgumentMatchingStrategies()
    {
        createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.three(isInstance(String.class), "World")).thenAnswer(ObjectProviderUtils.constant("World"));
            }
        });
    }

    @Test
    public void testStubReturn()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.stub()).thenStub(new Trainer<StubInterface>()
                {
                    @Override
                    protected void train(StubInterface trainee)
                    {
                        when(trainee.one("Hello")).thenReturn("World");
                    }
                });
            }
        });
        assertNotNull(proxy.stub());
        assertEquals("World", proxy.stub().one("Hello"));
    }

    @Test(expected = IllegalStateException.class)
    public void testThenBeforeWhen()
    {
        createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                thenThrow(new RuntimeException("Oops!"));
            }
        });
    }

    @Test(expected = IllegalArgumentException.class)
    public void testThrowExceptionWithException()
    {
        StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                trainee.voidMethod("Hello");
                thenThrow(new IllegalArgumentException("Nope!"));
            }
        });
        proxy.voidMethod("Hello");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testThrowExceptionWithProvidedException()
    {
        StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                trainee.voidMethod("Hello");
                thenThrow(ObjectProviderUtils.constant(new IllegalArgumentException("Nope!")));
            }
        });
        proxy.voidMethod("Hello");
    }

    @Test(expected = RuntimeException.class)
    public void testThrowingExceptionObject()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one("Hello")).thenThrow(new RuntimeException("No way, Jose!"));
            }
        });
        proxy.one("Hello");
    }

    @Test(expected = RuntimeException.class)
    public void testThrowingProvidedException()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one("Hello")).thenThrow(ObjectProviderUtils.constant(new RuntimeException("No way, Jose!")));
            }
        });
        proxy.one("Hello");
    }

    @Test(expected = IllegalStateException.class)
    public void testUsingWrongStub()
    {
        createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(final StubInterface parent)
            {
                when(parent.stub()).thenStub(new Trainer<StubInterface>()
                {
                    @Override
                    protected void train(final StubInterface child)
                    {
                        when(parent.one("Hello")).thenReturn("World");
                    }
                });
            }
        });
    }

    @Test
    public void testWithArgumentMatchers()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one(isInstance(String.class))).thenAnswer(ObjectProviderUtils.constant("World"));
            }
        });
        assertEquals("World", proxy.one("Hello"));
        assertEquals("World", proxy.one("Whatever"));
    }

    @Test
    public void testWithArrayParameter()
    {
        StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.arrayParameter("One", "Two", "Three")).thenReturn("Four");
            }
        });

        assertEquals("Four", proxy.arrayParameter("One", "Two", "Three"));
    }

    @Test
    public void testWithBooleanArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.booleanArray()).thenReturn(false, true, false);
            }
        });
        assertTrue(Arrays.equals(new boolean[]{false, true, false}, proxy.booleanArray()));
    }

    @Test
    public void testWithByteArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.byteArray()).thenReturn((byte) 1, (byte) 2);
            }
        });
        assertArrayEquals(new byte[]{1, 2}, proxy.byteArray());
    }

    @Test
    public void testWithCharArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.charArray()).thenReturn('a', 'b', 'c');
            }
        });
        assertArrayEquals(new char[]{'a', 'b', 'c'}, proxy.charArray());
    }

    @Test
    public void testWithDoubleArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.doubleArray()).thenReturn(1.0, 2.0);
            }
        });
        assertArrayEquals(new double[]{1.0, 2.0}, proxy.doubleArray(), 0.0);
    }

    @Test
    public void testWithFloatArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.floatArray()).thenReturn(1f, 2f);
            }
        });
        assertArrayEquals(new float[]{1f, 2f}, proxy.floatArray(), 0.0f);
    }

    @Test
    public void testWithIntArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.intArray()).thenReturn(1, 2);
            }
        });
        assertArrayEquals(new int[]{1, 2}, proxy.intArray());
    }

    @Test
    public void testWithLongArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.longArray()).thenReturn(1, 2);
            }
        });
        assertArrayEquals(new long[]{1, 2}, proxy.longArray());
    }

    @Test
    public void testWithMismatchedArgument()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one(eq("Hello"))).thenReturn("World");
            }
        });
        assertEquals("World", proxy.one("Hello"));
        assertEquals(null, proxy.one("Whatever"));
    }

    @Test
    public void testWithMultipleMethodsTrained()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one("Hello")).thenReturn("World");
                when(trainee.two("Foo")).thenReturn("Bar");
            }
        });
        assertEquals("World", proxy.one("Hello"));
        assertEquals("Bar", proxy.two("Foo"));
    }

    @Test
    public void testWithShortArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.shortArray()).thenReturn((short) 1, (short) 2);
            }
        });
        assertArrayEquals(new short[]{1, 2}, proxy.shortArray());
    }

    @Test
    public void testWithSingleMethodTrained()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.one("Hello")).thenReturn("World");
            }
        });
        assertEquals("World", proxy.one("Hello"));
        assertEquals(null, proxy.two("Whatever"));
        assertEquals(null, proxy.one("Mismatch!"));
    }

    @Test
    public void testWithStringArray()
    {
        final StubInterface proxy = createProxy(new Trainer<StubInterface>()
        {
            @Override
            protected void train(StubInterface trainee)
            {
                when(trainee.stringArray()).thenReturn("One", "Two");
            }
        });
        assertArrayEquals(new String[]{"One", "Two"}, proxy.stringArray());
    }
}
