package com.bumptech.glide.request;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.provider.LoadProvider;
import com.bumptech.glide.request.target.Target;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;

import java.io.IOException;
import java.io.InputStream;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(RobolectricTestRunner.class)
public class GenericRequestTest {
    private RequestHarness harness;

    @SuppressWarnings("unchecked")
    private static class RequestHarness {
        Engine engine = mock(Engine.class);
        Object model = new Object();
        Target<Object> target = mock(Target.class);
        Context context = Robolectric.application;
        Resource<Object> resource = mock(Resource.class);
        RequestCoordinator requestCoordinator = mock(RequestCoordinator.class);
        Priority priority = Priority.NORMAL;
        int placeholderResourceId = 0;
        Drawable placeholderDrawable = null;
        int errorResourceId = 0;
        Drawable errorDrawable = null;
        LoadProvider<Object, Object, Object, Object> loadProvider = mock(LoadProvider.class);
        ResourceDecoder<InputStream, Object> cacheDecoder = mock(ResourceDecoder.class);
        ResourceDecoder<Object, Object> sourceDecoder = mock(ResourceDecoder.class);
        ResourceEncoder<Object> encoder = mock(ResourceEncoder.class);
        ResourceTranscoder transcoder = mock(ResourceTranscoder.class);
        Encoder<Object> sourceEncoder = mock(Encoder.class);
        RequestListener<Object, Object> requestListener = mock(RequestListener.class);
        boolean skipMemoryCache;
        GlideAnimationFactory<Object> factory = mock(GlideAnimationFactory.class);
        int overrideWidth = -1;
        int overrideHeight = -1;
        boolean cacheSource = false;

        public RequestHarness() {
            ModelLoader<Object, Object> modelLoader = mock(ModelLoader.class);
            when(loadProvider.getModelLoader()).thenReturn(modelLoader);
            when(loadProvider.getCacheDecoder()).thenReturn(cacheDecoder);
            when(loadProvider.getSourceDecoder()).thenReturn(sourceDecoder);
            when(loadProvider.getSourceEncoder()).thenReturn(sourceEncoder);
            when(loadProvider.getEncoder()).thenReturn(encoder);
            when(loadProvider.getTranscoder()).thenReturn(transcoder);
            when(requestCoordinator.canSetImage(any(Request.class))).thenReturn(true);
            when(requestCoordinator.canSetPlaceholder(any(Request.class))).thenReturn(true);

            when(resource.get()).thenReturn(new Object());
        }

        public GenericRequest<Object, Object, Object, Object> getRequest() {
            return GenericRequest.obtain(loadProvider,
                    model,
                    context,
                    priority,
                    target,
                    1f,
                    placeholderDrawable,
                    placeholderResourceId,
                    errorDrawable,
                    errorResourceId,
                    requestListener,
                    requestCoordinator,
                    engine,
                    mock(Transformation.class),
                    Object.class,
                    skipMemoryCache,
                    factory,
                    overrideWidth,
                    overrideHeight,
                    cacheSource);
        }
    }

    @Before
    public void setUp() {
        harness = new RequestHarness();
    }

    @Test(expected = NullPointerException.class)
    public void testThrowsWhenMissingCacheDecoder() {
        when(harness.loadProvider.getCacheDecoder()).thenReturn(null);

        harness.getRequest();
    }

    @Test(expected = NullPointerException.class)
    public void testThrowsWhenMissingSourceDecoder() {
        when(harness.loadProvider.getSourceDecoder()).thenReturn(null);

        harness.getRequest();
    }

    @Test(expected =  NullPointerException.class)
    public void testThrowsWhenMissingEncoder() {
        when(harness.loadProvider.getEncoder()).thenReturn(null);

        harness.getRequest();
    }

    @Test(expected =  NullPointerException.class)
    public void testThrowsWhenMissingTranscoder() {
        when(harness.loadProvider.getTranscoder()).thenReturn(null);

        harness.getRequest();
    }

    @Test(expected = NullPointerException.class)
    public void testThrowsWhenMissingModelLoader() {
        when(harness.loadProvider.getModelLoader()).thenReturn(null);

        harness.getRequest();
    }

    @Test(expected = NullPointerException.class)
    public void testThrowsWhenMissingSourceEncoder() {
        when(harness.loadProvider.getSourceEncoder()).thenReturn(null);

        harness.getRequest();
    }

    @Test
    public void testIsNotCompleteBeforeReceivingResource() {
        GenericRequest request = harness.getRequest();

        assertFalse(request.isComplete());
    }

    @Test
    public void testCanHandleNullResources() {
        GenericRequest request = harness.getRequest();

        request.onResourceReady(null);

        assertTrue(request.isFailed());
    }

    @Test
    public void testIsCompleteAfterReceivingResource() {
        GenericRequest request = harness.getRequest();

        when(harness.resource.get()).thenReturn(new Object());
        request.onResourceReady(harness.resource);

        assertTrue(request.isComplete());
    }

    @Test
    public void testResourceIsNotCompleteWhenAskingCoordinatorIfCanSetImage() {
        RequestCoordinator requestCoordinator = mock(RequestCoordinator.class);
        doAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Request request = (Request) invocation.getArguments()[0];
                assertFalse(request.isComplete());
                return true;
            }
        }).when(requestCoordinator).canSetImage(any(Request.class));

        harness.requestCoordinator = requestCoordinator;
        GenericRequest request = harness.getRequest();

        when(harness.resource.get()).thenReturn(new Object());
        request.onResourceReady(harness.resource);

        verify(requestCoordinator).canSetImage(eq(request));
    }

    @Test
    public void testIsNotFailedWithoutException() {
        GenericRequest request = harness.getRequest();

        assertFalse(request.isFailed());
    }

    @Test
    public void testIsFailedAfterException() {
        GenericRequest request = harness.getRequest();

        request.onException(new Exception("test"));
        assertTrue(request.isFailed());
    }

    @Test
    public void testEngineLoadPassedCorrectPriority() {
        Priority expected = Priority.HIGH;
        harness.priority = expected;
        GenericRequest request = harness.getRequest();


        request.onSizeReady(100, 100);

        verify(harness.engine).load(anyInt(), anyInt(), any(ResourceDecoder.class),
                any(DataFetcher.class), anyBoolean(), any(Encoder.class), any(ResourceDecoder.class),
                any(Transformation.class), any(ResourceEncoder.class), any(ResourceTranscoder.class), eq(expected),
                anyBoolean(), any(ResourceCallback.class));
    }

    @Test
    public void testEngineLoadCancelledOnCancel() {
        Engine.LoadStatus loadStatus = mock(Engine.LoadStatus.class);
        when(harness.engine.load(anyInt(), anyInt(), any(ResourceDecoder.class),
                any(DataFetcher.class), anyBoolean(), any(Encoder.class), any(ResourceDecoder.class),
                any(Transformation.class), any(ResourceEncoder.class), any(ResourceTranscoder.class),
                any(Priority.class), anyBoolean(), any(ResourceCallback.class))).thenReturn(loadStatus);

        GenericRequest request = harness.getRequest();

        request.onSizeReady(100, 100);
        request.cancel();

        verify(loadStatus).cancel();
    }

    @Test
    public void testResourceIsRecycledOnClear() {
        GenericRequest request = harness.getRequest();

        when(harness.resource.get()).thenReturn(new Object());
        request.onResourceReady(harness.resource);
        request.clear();

        verify(harness.resource).release();
    }

    @Test
    public void testPlaceholderResourceIsSet() {
        final int expectedId = 12345;
        Drawable expected = new ColorDrawable(Color.RED);

        Context context = mockContextToReturn(expectedId, expected);
        MockTarget target = new MockTarget();

        harness.context = context;
        harness.placeholderResourceId = expectedId;
        harness.target = target;
        GenericRequest request = harness.getRequest();
        request.run();

        assertEquals(expected, target.currentPlaceholder);
    }

    @Test
    public void testPlaceholderDrawableIsSet() {
        Drawable expected = new ColorDrawable(Color.RED);

        MockTarget target = new MockTarget();

        harness.placeholderDrawable = expected;
        harness.target = target;
        GenericRequest request = harness.getRequest();
        request.run();

        assertEquals(expected, target.currentPlaceholder);
    }

    @Test
    public void testErrorResourceIsSetOnLoadFailed() {
        final int expectedId = 12345;
        Drawable expected = new ColorDrawable(Color.RED);

        Context context = mockContextToReturn(expectedId, expected);
        MockTarget target = new MockTarget();

        harness.context = context;
        harness.errorResourceId = expectedId;
        harness.target = target;
        GenericRequest request = harness.getRequest();

        request.onException(null);

        assertEquals(expected, target.currentPlaceholder);
    }

    @Test
    public void testErrorDrawableIsSetOnLoadFailed() {
        Drawable expected = new ColorDrawable(Color.RED);

        MockTarget target = new MockTarget();

        harness.errorDrawable = expected;
        harness.target = target;
        GenericRequest request = harness.getRequest();

        request.onException(null);

        assertEquals(expected, target.currentPlaceholder);
    }

    @Test
    public void setTestPlaceholderDrawableSetOnNullModel() {
        Drawable placeholder = new ColorDrawable(Color.RED);

        MockTarget target = new MockTarget();

        harness.placeholderDrawable = placeholder;
        harness.target = target;
        harness.model = null;
        GenericRequest request = harness.getRequest();

        request.run();

        assertEquals(placeholder, target.currentPlaceholder);
    }

    @Test
    public void testErrorDrawableSetOnNullModel() {
        Drawable placeholder = new ColorDrawable(Color.RED);
        Drawable errorPlaceholder = new ColorDrawable(Color.GREEN);

        MockTarget target = new MockTarget();

        harness.placeholderDrawable = placeholder;
        harness.errorDrawable = errorPlaceholder;
        harness.target = target;
        harness.model = null;
        GenericRequest request = harness.getRequest();

        request.run();

        assertEquals(errorPlaceholder, target.currentPlaceholder);
    }

    @Test
    public void testIsNotRunningBeforeRunCalled() {
        assertFalse(harness.getRequest().isRunning());
    }

    @Test
    public void testIsRunningAfterRunCalled() {
        Request request = harness.getRequest();
        request.run();
        assertTrue(request.isRunning());
    }

    @Test
    public void testIsNotRunningAfterComplete() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();
        request.onResourceReady(harness.resource);

        assertFalse(request.isRunning());
    }

    @Test
    public void testIsNotRunningAfterFailing() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();
        request.onException(new RuntimeException("Test"));

        assertFalse(request.isRunning());
    }

    @Test
    public void testIsNotRunningAfterClear() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();
        request.clear();

        assertFalse(request.isRunning());
    }

    @Test
    public void testCallsTargetOnResourceReadyIfNoRequestListener() {
        harness.requestListener = null;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onResourceReady(harness.resource);

        verify(harness.target).onResourceReady(eq(harness.resource.get()), any(GlideAnimation.class));
    }

    @Test
    public void testCallsTargetOnResourceReadyIfRequestListenerReturnsFalse() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestListener.onResourceReady(anyObject(), anyObject(), eq(harness.target),
                anyBoolean(), anyBoolean())).thenReturn(false);
        request.onResourceReady(harness.resource);

        verify(harness.target).onResourceReady(eq(harness.resource.get()), any(GlideAnimation.class));
    }

    @Test
    public void testDoesNotCallTargetOnResourceReadyIfRequestListenerReturnsTrue() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestListener.onResourceReady(anyObject(), anyObject(), eq(harness.target),
                anyBoolean(), anyBoolean())).thenReturn(true);
        request.onResourceReady(harness.resource);

        verify(harness.target, never()).onResourceReady(anyObject(), any(GlideAnimation.class));
    }

    @Test
    public void testCallsTargetOnExceptionIfNoRequestListener() {
        harness.requestListener = null;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onException(new IOException("test"));

        verify(harness.target).setPlaceholder(eq(harness.errorDrawable));
    }

    @Test
    public void testCallsTargetOnExceptionIfRequestListenerReturnsFalse() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestListener.onException(any(Exception.class), anyObject(), eq(harness.target), anyBoolean()))
                .thenReturn(false);
        request.onException(new IOException("test"));

        verify(harness.target).setPlaceholder(eq(harness.errorDrawable));
    }

    @Test
    public void testDoesNotCallTargetOnExceptionIfRequestListenerReturnsTrue() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestListener.onException(any(Exception.class), anyObject(), eq(harness.target), anyBoolean()))
                .thenReturn(true);
        request.onException(new IllegalArgumentException("test"));

        verify(harness.target, never()).setPlaceholder(any(Drawable.class));
    }

    @Test
    public void testRequestListenerIsCalledWithResourceResult() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(eq(harness.resource.get()), anyObject(), any(Target.class),
                anyBoolean(), anyBoolean());
    }

    @Test
    public void testRequestListenerIsCalledWithModel() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), eq(harness.model), any(Target.class),
                anyBoolean(), anyBoolean());
    }

    @Test
    public void testRequestListenerIsCalledWithTarget() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), eq(harness.target), anyBoolean(),
                anyBoolean());
    }

    @Test
    public void testRequestListenerIsCalledWithLoadedFromMemoryIfLoadCompletesSynchronously() {
        final GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.engine.load(anyInt(), anyInt(), any(ResourceDecoder.class), any(DataFetcher.class),
                anyBoolean(), any(Encoder.class), any(ResourceDecoder.class), any(Transformation.class),
                any(ResourceEncoder.class), any(ResourceTranscoder.class), any(Priority.class), anyBoolean(),
                any(ResourceCallback.class))).thenAnswer(new Answer<Object>() {
                    @Override
                    public Object answer(InvocationOnMock invocation) throws Throwable {
                        request.onResourceReady(harness.resource);
                        return null;
                    }
                });
        request.onSizeReady(100, 100);
        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), any(Target.class), eq(true),
                anyBoolean());
    }

    @Test
    public void testRequestListenerIsCalledWithNotLoadedFromMemoryCacheIfLoadCompletesAsynchronously() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onSizeReady(100, 100);
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), any(Target.class), eq(false),
                anyBoolean());
    }

    @Test
    public void testRequestListenerIsCalledWithIsFirstResourceIfNoRequestCoordinator() {
        harness.requestCoordinator = null;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), any(Target.class), anyBoolean(),
                eq(true));
    }

    @Test
    public void testRequestListenerIsCalledWithIsFirstImageIfRequestCoordinatorReturnsNoRequestComplete() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestCoordinator.isAnyRequestComplete()).thenReturn(false);
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), any(Target.class), anyBoolean(),
                eq(true));
    }

    @Test
    public void testRequestListenerIsCalledWithNotIsFirstRequestIfRequestCoordinatorReturnsARequestComplete() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestCoordinator.isAnyRequestComplete()).thenReturn(true);
        request.onResourceReady(harness.resource);

        verify(harness.requestListener).onResourceReady(anyObject(), anyObject(), any(Target.class), anyBoolean(),
                eq(false));
    }

    @Test
    public void testTargetIsCalledWithAnimationFromFactory() {
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        GlideAnimation<Object> glideAnimation = mock(GlideAnimation.class);
        when(harness.factory.build(anyBoolean(), anyBoolean())).thenReturn(glideAnimation);
        request.onResourceReady(harness.resource);

        verify(harness.target).onResourceReady(eq(harness.resource.get()), eq(glideAnimation));
    }

    @Test
    public void testCallsGetSizeIfOverrideWidthIsLessThanZero() {
        harness.overrideWidth = -1;
        harness.overrideHeight = 100;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();

        verify(harness.target).getSize(any(Target.SizeReadyCallback.class));
    }

    @Test
    public void testCallsGetSizeIfOverrideHeightIsLessThanZero() {
        harness.overrideHeight = -1;
        harness.overrideWidth = 100;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();

        verify(harness.target).getSize(any(Target.SizeReadyCallback.class));
    }

    @Test
    public void testDoesNotCallGetSizeIfOverrideWidthAndHeightAreSet() {
        harness.overrideWidth = 100;
        harness.overrideHeight = 100;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();

        verify(harness.target, never()).getSize(any(Target.SizeReadyCallback.class));
    }

    @Test
    public void testCallsEngineWithOverrideWidthAndHeightIfSet() {
        harness.overrideWidth = 1;
        harness.overrideHeight = 2;
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        request.run();

        verify(harness.engine).load(eq(harness.overrideWidth), eq(harness.overrideHeight),
                any(ResourceDecoder.class), any(DataFetcher.class), anyBoolean(), any(Encoder.class),
                any(ResourceDecoder.class), any(Transformation.class), any(ResourceEncoder.class),
                any(ResourceTranscoder.class), any(Priority.class), anyBoolean(), any(ResourceCallback.class));
    }

    @Test
    public void testDoesNotSetErrorDrawableIfRequestCoordinatorDoesntAllowIt() {
        harness.errorDrawable = new ColorDrawable(Color.RED);
        GenericRequest<Object, Object, Object, Object> request = harness.getRequest();
        when(harness.requestCoordinator.canSetPlaceholder(any(Request.class))).thenReturn(false);
        request.onException(new IOException("Test"));

        verify(harness.target, never()).setPlaceholder(any(Drawable.class));
    }

    private Context mockContextToReturn(int resourceId, Drawable drawable) {
        Resources resources = mock(Resources.class);
        Context context = mock(Context.class);

        when(context.getApplicationContext()).thenReturn(context);
        when(context.getResources()).thenReturn(resources);
        when(resources.getDrawable(eq(resourceId))).thenReturn(drawable);

        return context;
    }

    private static class MockTarget implements Target {
        private Drawable currentPlaceholder;

        @Override
        public void onResourceReady(Object resource, GlideAnimation glideAnimation) {
            currentPlaceholder = null;
        }

        @Override
        public void setPlaceholder(Drawable placeholder) {
            currentPlaceholder = placeholder;
        }

        @Override
        public void getSize(SizeReadyCallback cb) {
        }

        @Override
        public void setRequest(Request request) {
        }

        @Override
        public Request getRequest() {
            return null;
        }
    }
}
