/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.servicecomb.transport.rest.vertx;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.servicecomb.config.ConfigUtil;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.SCBEngine;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.core.bootstrap.SCBBootstrap;
import org.apache.servicecomb.core.transport.AbstractTransport;
import org.apache.servicecomb.foundation.common.Holder;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;

import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.CorsHandler;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;

public class TestRestServerVerticle {

  private RestServerVerticle instance = null;

  Promise<Void> startPromise = null;

  @Before
  public void setUp() {
    ConfigUtil.installDynamicConfig();
    instance = new RestServerVerticle();
    startPromise = Promise.promise();

    SCBBootstrap.createSCBEngineForTest();
  }

  @After
  public void tearDown() {
    instance = null;
    startPromise = null;
    SCBEngine.getInstance().destroy();
    ArchaiusUtils.resetConfig();
  }

  @Test
  public void testRestServerVerticleWithRouter(@Mocked Transport transport, @Mocked Vertx vertx,
      @Mocked Context context,
      @Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {
    URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080");
    new Expectations() {
      {
        transport.parseAddress("http://127.0.0.1:8080");
        result = endpointObject;
      }
    };
    Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080");

    new Expectations() {
      {
        context.config();
        result = jsonObject;
        jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
        result = endpiont;
      }
    };
    RestServerVerticle server = new RestServerVerticle();
    // process stuff done by Expectations
    server.init(vertx, context);
    server.start(startPromise);
  }

  @Test
  public void testRestServerVerticleWithRouterSSL(@Mocked Transport transport, @Mocked Vertx vertx,
      @Mocked Context context,
      @Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {
    URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080?sslEnabled=true");
    new Expectations() {
      {
        transport.parseAddress("http://127.0.0.1:8080?sslEnabled=true");
        result = endpointObject;
      }
    };
    Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080?sslEnabled=true");

    new Expectations() {
      {
        context.config();
        result = jsonObject;
        jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
        result = endpiont;
      }
    };
    RestServerVerticle server = new RestServerVerticle();
    // process stuff done by Expectations
    server.init(vertx, context);
    server.start(startPromise);
  }

  @Test
  public void testRestServerVerticleWithHttp2(@Mocked Transport transport, @Mocked Vertx vertx,
      @Mocked Context context,
      @Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) {
    URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080?protocol=http2");
    new Expectations() {
      {
        transport.parseAddress("http://127.0.0.1:8080?protocol=http2");
        result = endpointObject;
      }
    };
    Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080?protocol=http2");

    new Expectations() {
      {
        context.config();
        result = jsonObject;
        jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
        result = endpiont;
      }
    };
    RestServerVerticle server = new RestServerVerticle();
    boolean status = false;
    try {
      server.init(vertx, context);
      server.start(startPromise);
    } catch (Exception e) {
      status = true;
    }
    Assertions.assertFalse(status);
  }

  @Test
  public void testStartFutureAddressEmpty() {
    boolean status = false;
    try {
      instance.start(startPromise);
    } catch (Exception ex) {
      status = true;
    }
    Assertions.assertFalse(status);
  }

  @Test
  public void testStartFutureAddressNotEmpty() {
    boolean status = false;
    MockForRestServerVerticle.getInstance().mockTransportConfig();
    MockForRestServerVerticle.getInstance().mockRestServerVerticle();
    try {
      instance.start(startPromise);
    } catch (Exception ex) {
      status = true;
    }
    Assertions.assertFalse(status);
  }

  @Test
  public void testMountCorsHandler() {
    ArchaiusUtils.setProperty("servicecomb.cors.enabled", true);
    ArchaiusUtils.setProperty("servicecomb.cors.allowedMethod", "GET,PUT,POST");
    ArchaiusUtils.setProperty("servicecomb.cors.allowedHeader", "abc,def");
    ArchaiusUtils.setProperty("servicecomb.cors.exposedHeader", "abc2,def2");
    ArchaiusUtils.setProperty("servicecomb.cors.maxAge", 1);
    Set<HttpMethod> methodSet = new HashSet<>(3);
    methodSet.add(HttpMethod.GET);
    methodSet.add(HttpMethod.PUT);
    methodSet.add(HttpMethod.POST);
    AtomicInteger counter = new AtomicInteger(0);

    CorsHandler corsHandler = new MockUp<CorsHandler>() {
      @Mock
      CorsHandler allowCredentials(boolean allow) {
        Assertions.assertFalse(allow);
        counter.incrementAndGet();
        return null;
      }

      @Mock
      CorsHandler allowedHeaders(Set<String> headerNames) {
        MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder("abc", "def"));
        counter.incrementAndGet();
        return null;
      }

      @Mock
      CorsHandler exposedHeaders(Set<String> headerNames) {
        MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder("abc2", "def2"));
        counter.incrementAndGet();
        return null;
      }

      @Mock
      CorsHandler allowedMethod(HttpMethod method) {
        Assertions.assertTrue(methodSet.contains(method));
        counter.incrementAndGet();
        methodSet.remove(method);
        return null;
      }

      @Mock
      CorsHandler maxAgeSeconds(int maxAgeSeconds) {
        Assertions.assertEquals(1, maxAgeSeconds);
        counter.incrementAndGet();
        return null;
      }
    }.getMockInstance();

    new MockUp<RestServerVerticle>() {
      @Mock
      CorsHandler getCorsHandler(String corsAllowedOrigin) {
        Assertions.assertEquals("*", corsAllowedOrigin);
        return corsHandler;
      }
    };
    Router router = Mockito.mock(Router.class);
    Mockito.when(router.route()).thenReturn(Mockito.mock(Route.class));

    RestServerVerticle server = new RestServerVerticle();

    server.mountCorsHandler(router);
    Assertions.assertEquals(7, counter.get());
  }

  @Test
  public void mountGlobalRestFailureHandler() {
    Router mainRouter = Mockito.mock(Router.class);
    Holder<Handler<RoutingContext>> handlerHolder = new Holder<>();
    Holder<Route> routeHolder = new Holder<>();
    Route route = new MockUp<Route>() {
      @Mock
      Route failureHandler(Handler<RoutingContext> failureHandler) {
        handlerHolder.value = failureHandler;
        return null;
      }

      @Mock
      Route handler(io.vertx.core.Handler<io.vertx.ext.web.RoutingContext> requestHandler) {
        return routeHolder.value;
      }
    }.getMockInstance();
    routeHolder.value = route;

    Mockito.when(mainRouter.route()).thenReturn(route);

    RestServerVerticle restServerVerticle = new RestServerVerticle();

    restServerVerticle.mountGlobalRestFailureHandler(mainRouter);
    Assertions.assertNotNull(handlerHolder.value);

    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
    HttpServerResponse response = Mockito.mock(HttpServerResponse.class);
    Mockito.when(response.setStatusCode(500)).thenReturn(response);
    Mockito.when(response.putHeader("Content-Type", "application/json")).thenReturn(response);
    Mockito.when(routingContext.response()).thenReturn(response);

    handlerHolder.value.handle(routingContext);
    Mockito.verify(response).end("{\"message\":\"unknown error\"}");
  }
}
