package org.vovkasm.WebImage;

import android.graphics.Bitmap;

import com.bumptech.glide.load.model.GlideUrl;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.JavaOnlyArray;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.queue.MessageQueueThreadSpec;
import com.facebook.react.bridge.queue.QueueThreadExceptionHandler;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.bridge.queue.ReactQueueConfigurationImpl;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
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)
@Config(manifest= Config.NONE)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Arguments.class)
public class RequestListenerTest {
    @Rule
    public PowerMockRule rule = new PowerMockRule();

    private ReactApplicationContext appContext;
    private ThemedReactContext themedReactContext;
    private RCTEventEmitter eventEmitter;
    private WebImageViewManager viewManager;

    @Before
    public void setUp () {
        PowerMockito.mockStatic(Arguments.class);

        PowerMockito.when(Arguments.createArray()).thenAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return new JavaOnlyArray();
            }
        });
        PowerMockito.when(Arguments.createMap()).thenAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return new JavaOnlyMap();
            }
        });

        eventEmitter = mock(RCTEventEmitter.class);

        appContext = new ReactApplicationContext(RuntimeEnvironment.application);
        appContext.initializeWithInstance(createMockCatalystInstance());

        themedReactContext = new ThemedReactContext(appContext, appContext);
        viewManager = new WebImageViewManager();
    }

    @Test
    public void testRequestListenerOnLoad () {
        WebImageView imageView = viewManager.createViewInstance(themedReactContext);
        imageView.setImageUri(new GlideUrl("http://fake/favicon.png"));

        verify(eventEmitter, never()).receiveEvent(anyInt(), anyString(), any(WritableMap.class));

        WebImageViewTarget target = new WebImageViewTarget(imageView);
        Bitmap bitmap = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888);

        viewManager.mRequestListener.onResourceReady(bitmap, null, target, null, true);

        WritableMap expectedSource = Arguments.createMap();
        expectedSource.putString("uri", "http://fake/favicon.png");
        expectedSource.putInt("width", 64);
        expectedSource.putInt("height", 64);
        WritableMap expectedEvent = Arguments.createMap();
        expectedEvent.putMap("source", expectedSource);

        verify(eventEmitter).receiveEvent(-1, "onWebImageLoad", expectedEvent);
    }

    public CatalystInstance createMockCatalystInstance() {
        ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder()
                .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec())
                .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec())
                .build();
        ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create(
                spec,
                new QueueThreadExceptionHandler() {
                    @Override
                    public void handleException(Exception e) {
                        throw new RuntimeException(e);
                    }
                });

        CatalystInstance reactInstance = mock(CatalystInstance.class);
        when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration);
        when(reactInstance.getNativeModule(UIManagerModule.class))
                .thenReturn(mock(UIManagerModule.class));
        when(reactInstance.getJSModule(RCTEventEmitter.class))
                .thenReturn(eventEmitter);

        return reactInstance;
    }
}

@@ -2016,24 +2016,67 @@
 ockRule();%0A%0A
+    private RCTEventEmitter mEventEmitter;%0A
     private 
@@ -2099,19 +2099,28 @@
 Context 
-app
+mApplication
 Context;
@@ -2151,17 +2151,18 @@
 Context 
-t
+mT
 hemedRea
@@ -2188,34 +2188,38 @@
 ate 
-RCTEventEmitter eventEmitt
+WebImageViewManager mViewManag
 er;%0A
@@ -2246,27 +2246,19 @@
 View
-Manager viewManager
+ mImageView
 ;%0A%0A 
@@ -2867,17 +2867,18 @@
         
-e
+mE
 ventEmit
@@ -2917,27 +2917,36 @@
 );%0A%0A        
-app
+mApplication
 Context = ne
@@ -3012,19 +3012,28 @@
         
-app
+mApplication
 Context.
@@ -3095,17 +3095,18 @@
         
-t
+mT
 hemedRea
@@ -3144,23 +3144,41 @@
 ext(
-appContext, app
+mApplicationContext, mApplication
 Cont
@@ -3183,33 +3183,34 @@
 ntext);%0A        
-v
+mV
 iewManager = new
@@ -3237,94 +3237,19 @@
 ();%0A
-    %7D%0A%0A    @Test%0A    public void testRequestListenerOnLoad () %7B%0A        WebImageView i
+%0A        mI
 mage
@@ -3255,17 +3255,18 @@
 eView = 
-v
+mV
 iewManag
@@ -3287,17 +3287,18 @@
 nstance(
-t
+mT
 hemedRea
@@ -3317,17 +3317,18 @@
         
-i
+mI
 mageView
@@ -3378,24 +3378,84 @@
 con.png%22));%0A
+    %7D%0A%0A    @Test%0A    public void testOnLoadEventEmitted () %7B
 %0A        ver
@@ -3450,33 +3450,34 @@
 %0A        verify(
-e
+mE
 ventEmitter, nev
@@ -3603,17 +3603,18 @@
 wTarget(
-i
+mI
 mageView
@@ -3703,17 +3703,18 @@
         
-v
+mV
 iewManag
@@ -4133,17 +4133,18 @@
  verify(
-e
+mE
 ventEmit
@@ -5281,17 +5281,18 @@
 nReturn(
-e
+mE
 ventEmit

restructure test