package fr.free.nrw.commons.nearby;

import android.support.annotation.NonNull;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererViewHolder;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowDrawable;

import java.util.Collections;

import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.TestCommonsApplication;
import fr.free.nrw.commons.location.LatLng;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class)
public class NearbyAdapterFactoryTest {

    private static final Place PLACE = new Place("name", Place.Label.AIRPORT,
            "desc", null, new LatLng(38.6270, -90.1994, 0), null);
    private static final Place UNKNOWN_PLACE = new Place("name", Place.Label.UNKNOWN,
            "desc", null, new LatLng(39.7392, -104.9903, 0), null);
    private Place clickedPlace;

    @Test
    public void factoryHandlesNullListAndNullListener() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
        RVRendererAdapter<Place> result = testObject.create(null);
        assertNotNull(result);
        assertEquals(0, result.getItemCount());
    }

    @Test
    public void factoryHandlesEmptyListAndNullListener() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
        RVRendererAdapter<Place> result = testObject.create(Collections.<Place>emptyList());
        assertNotNull(result);
        assertEquals(0, result.getItemCount());
    }

    @Test
    public void factoryHandlesNonEmptyListAndNullListener() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
        RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
        assertNotNull(result);
        assertEquals(1, result.getItemCount());
        assertEquals(PLACE, result.getItem(0));
    }

    @Test
    public void rendererCorrectlyBound() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
        RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));

        RendererViewHolder viewHolder = renderComponent(result);

        assertNotNull(viewHolder.itemView.findViewById(R.id.tvName));
        assertEquals("name",
                ((TextView) viewHolder.itemView.findViewById(R.id.tvName)).getText().toString());

        assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
        assertEquals("airport",
                ((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());

        assertNotNull(viewHolder.itemView.findViewById(R.id.distance));
        assertEquals("",
                ((TextView) viewHolder.itemView.findViewById(R.id.distance)).getText().toString());

        assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
        ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
        ShadowDrawable shadow  = Shadows.shadowOf(imageView.getDrawable());
        assertEquals(R.drawable.round_icon_airport, shadow.getCreatedFromResId());
    }

    @Test
    public void rendererCorrectlyBoundForUnknownPlace() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
        RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(UNKNOWN_PLACE));

        RendererViewHolder viewHolder = renderComponent(result);

        assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
        assertEquals("no description found",
                ((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());

        assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
        ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
        ShadowDrawable shadow  = Shadows.shadowOf(imageView.getDrawable());
        assertEquals(R.drawable.round_icon_unknown, shadow.getCreatedFromResId());
    }

    @Test
    public void clickView() {
        NearbyAdapterFactory testObject = new NearbyAdapterFactory(new MockPlaceClickedListener());
        RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
        RendererViewHolder viewHolder = renderComponent(result);

        viewHolder.itemView.performClick();

        assertEquals(PLACE, clickedPlace);
    }

    @NonNull
    private RendererViewHolder renderComponent(RVRendererAdapter<Place> result) {
        FrameLayout viewGroup = new FrameLayout(RuntimeEnvironment.application);
        int itemViewType = result.getItemViewType(0);
        RendererViewHolder viewHolder = result.onCreateViewHolder(viewGroup, itemViewType);
        assertNotNull(viewHolder);
        result.bindViewHolder(viewHolder, 0);
        return viewHolder;
    }

    private class MockPlaceClickedListener implements PlaceRenderer.PlaceClickedListener {
        @Override
        public void placeClicked(Place place) {
            clickedPlace = place;
        }
    }
}
@@ -1242,36 +1242,33 @@
 N,%0A            %22
-desc
+?
 %22, null, new Lat
@@ -1294,32 +1294,116 @@
 903, 0), null);%0A
+    // %5E %22?%22 is a special value for unknown class names from Wikidata query results%0A
     private Plac
@@ -2692,32 +2692,94 @@
 onent(result);%0A%0A
+        // test that the values we gave are actually rendered%0A
         assertNo
@@ -2853,22 +2853,26 @@
 tEquals(
-%22
+PLACE.
 name
-%22
 ,%0A      
@@ -3059,17 +3059,34 @@
 als(
-%22airport%22
+PLACE.getLongDescription()
 ,%0A  
@@ -4108,12 +4108,61 @@
 als(
-%22no 
+RuntimeEnvironment.application.getString(R.string.no_
 desc
@@ -4172,15 +4172,15 @@
 tion
- 
+_
 found
-%22
+)
 ,%0A  

Fix NearbyAdapterFactoryTest by reflecting PlaceRender's new behavior