package grok.core;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.put;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import org.geojson.Point;
import org.junit.Rule;
import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.google.common.base.Defaults;

import feign.Feign;
import feign.FeignException;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;

public class GrokApiTest {
  @Rule
  public final WireMockRule server = new WireMockRule(0);

  private GrokApi client() {
    return Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .target(GrokApi.class, "http://localhost:" + server.port());
  }

  @Test
  public void zz() throws Exception {
    for (Method m : GrokApi.class.getDeclaredMethods()) {
      try {
      m.invoke(client(), dummyParametersOfTypes(m.getParameterTypes()));
      } catch (InvocationTargetException e) {
        if (e.getCause() instanceof IllegalArgumentException || e.getCause() instanceof FeignException) {
          //ignore
        } else {
          throw e;
        }
      }
    }
  }

  private Object[] dummyParametersOfTypes(Class<?>[] parameters) {
    Object[] result = new Object[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
      result[i] = Defaults.defaultValue(parameters[i]);
    }
    return result;
  }

  @Test
  public void crags() throws Exception {
    Crag c = Crag.create()
                 .id(1l)
                 .name("crag")
                 .city("City")
                 .country("Country")
                 .state("State")
                 .regionId(1l)
                 .location(new Point(1.0, 1.0))
                 .build();
    List<Crag> expected = Arrays.asList(c);

    server.stubFor(get(urlEqualTo(GrokApi.CRAGS_ENDPOINT)).willReturn(aResponse().withBody(json(expected))));
    List<Crag> actual = client().crags();

    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void climbs() throws Exception {
    Route expected = Route.create()
                          .id(1l)
                          .cragId(1l).grokRating(Rating.of(0))
                          .image(Image.of("1", "title", "url"))
                          .name("Super Climb")
                          .grade(ClimbingGrade.yds("5.5")).thumbsDown(Count.of(0)).thumbsUp(Count.of(1))
                          .searchIndex("Super Climb 5.5")
                          .build();

    server.stubFor(get(urlEqualTo(GrokApi.ROUTES_ENDPOINT + "/dummy")).willReturn(aResponse().withBody(json(expected))));
    Route actual = client().route("dummy");

    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void testUpdateRoute() throws Exception {
    Route route = Route.create()
        .id(1l)
        .cragId(1l).grokRating(Rating.of(0))
        .image(Image.of("1", "title", "url"))
        .name("Super Climb")
        .grade(ClimbingGrade.yds("5.5")).thumbsDown(Count.of(0)).thumbsUp(Count.of(1))
        .searchIndex("Super Climb 5.5")
        .build();
    Id expected = Id.of("123123");

    server.stubFor(put(urlEqualTo(GrokApi.ROUTES_ENDPOINT + "/")).willReturn(aResponse().withBody(json(expected))));
    Id actual = client().update(route);

    assertThat(actual).isEqualTo(expected);
  }

  private static String json(Object json) throws Exception {
    return new ObjectMapper().writeValueAsString(json);
  }
}

@@ -357,93 +357,8 @@
 t;%0A%0A
-import java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0A
 impo
@@ -590,95 +590,26 @@
 le;%0A
-import com.google.common.base.Defaults;%0A%0Aimport feign.Feign;%0Aimport feign.FeignExceptio
+%0Aimport feign.Feig
 n;%0Ai
@@ -1012,689 +1012,8 @@
  %7D%0A%0A
-  @Test%0A  public void zz() throws Exception %7B%0A    for (Method m : GrokApi.class.getDeclaredMethods()) %7B%0A      try %7B%0A      m.invoke(client(), dummyParametersOfTypes(m.getParameterTypes()));%0A      %7D catch (InvocationTargetException e) %7B%0A        if (e.getCause() instanceof IllegalArgumentException %7C%7C e.getCause() instanceof FeignException) %7B%0A          //ignore%0A        %7D else %7B%0A          throw e;%0A        %7D%0A      %7D%0A    %7D%0A  %7D%0A%0A  private Object%5B%5D dummyParametersOfTypes(Class%3C?%3E%5B%5D parameters) %7B%0A    Object%5B%5D result = new Object%5Bparameters.length%5D;%0A    for (int i = 0; i %3C parameters.length; i++) %7B%0A      result%5Bi%5D = Defaults.defaultValue(parameters%5Bi%5D);%0A    %7D%0A    return result;%0A  %7D%0A%0A
   @T

Remove method which meant only for debugging