package io.vertx.ext.auth.test.oauth2;

import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.oauth2.AccessToken;
import io.vertx.ext.auth.oauth2.OAuth2Auth;
import io.vertx.ext.auth.oauth2.OAuth2FlowType;
import io.vertx.test.core.VertxTestBase;
import org.junit.Test;

import java.net.URLEncoder;
import java.util.concurrent.CountDownLatch;

import static io.vertx.ext.auth.oauth2.impl.OAuth2API.stringify;

public class OAuth2FailureTest extends VertxTestBase {

  private static final JsonObject fixture = new JsonObject(
      "{" +
          "  \"access_token\": \"4adc339e0\"," +
          "  \"refresh_token\": \"ec1a59d298\"," +
          "  \"token_type\": \"bearer\"," +
          "  \"expires_in\": 7200" +
          "}");

  private static final JsonObject tokenConfig = new JsonObject()
      .put("code", "code")
      .put("redirect_uri", "http://callback.com");

  private static final JsonObject oauthConfig = new JsonObject()
      .put("code", "code")
      .put("redirect_uri", "http://callback.com")
      .put("client_secret", "client-secret")
      .put("grant_type", "authorization_code")
      .put("client_id", "client-id");

  private static final JsonObject authorizeConfig = new JsonObject()
      .put("redirect_uri", "http://localhost:3000/callback")
      .put("scope", "user")
      .put("state", "02afe928b");


  protected OAuth2Auth oauth2;
  private HttpServer server;
  private JsonObject config;
  private int code;

  @Override
  public void setUp() throws Exception {
    super.setUp();
    oauth2 = OAuth2Auth.create(vertx, OAuth2FlowType.AUTH_CODE, new JsonObject()
        .put("clientID", "client-id")
        .put("clientSecret", "client-secret")
        .put("site", "http://localhost:8080"));

    final CountDownLatch latch = new CountDownLatch(1);

    server = vertx.createHttpServer().requestHandler(req -> {
      if (req.method() == HttpMethod.POST && "/oauth/token".equals(req.path())) {
        req.setExpectMultipart(true).bodyHandler(buffer -> {
          // this is a tricky assertion because it assumes the order while it should not matter...
          assertEquals(stringify(config), buffer.toString());
          req.response().setStatusCode(code).end();
        });
      } else {
        req.response().setStatusCode(400).end();
      }
    }).listen(8080, ready -> {
      if (ready.failed()) {
        throw new RuntimeException(ready.cause());
      }
      // ready
      latch.countDown();
    });

    latch.await();
  }

  @Override
  public void tearDown() throws Exception {
    server.close();
    super.tearDown();
  }

  @Test
  public void getUnauthorizedToken() {
    config = oauthConfig;
    code = 401;
    oauth2.getToken(tokenConfig, res -> {
      if (res.failed()) {
        assertEquals("Unauthorized", res.cause().getMessage());
        testComplete();
      } else {
        fail("Should have failed");
      }
    });
    await();
  }

  @Test
  public void getTokenServerCrash() {
    config = oauthConfig;
    code = 500;
    oauth2.getToken(tokenConfig, res -> {
      if (res.failed()) {
        assertEquals("Internal Server Error", res.cause().getMessage());
        testComplete();
      } else {
        fail("Should have failed");
      }
    });
    await();
  }
}

@@ -548,278 +548,8 @@
  %7B%0A%0A
-  private static final JsonObject fixture = new JsonObject(%0A      %22%7B%22 +%0A          %22  %5C%22access_token%5C%22: %5C%224adc339e0%5C%22,%22 +%0A          %22  %5C%22refresh_token%5C%22: %5C%22ec1a59d298%5C%22,%22 +%0A          %22  %5C%22token_type%5C%22: %5C%22bearer%5C%22,%22 +%0A          %22  %5C%22expires_in%5C%22: 7200%22 +%0A          %22%7D%22);%0A%0A
   pr
@@ -965,202 +965,8 @@
 );%0A%0A
-  private static final JsonObject authorizeConfig = new JsonObject()%0A      .put(%22redirect_uri%22, %22http://localhost:3000/callback%22)%0A      .put(%22scope%22, %22user%22)%0A      .put(%22state%22, %2202afe928b%22);%0A%0A%0A
   pr

remove c&p unused fixture code