/*
 * 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.common.rest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.servicecomb.common.rest.definition.RestMetaUtils;
import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
import org.apache.servicecomb.common.rest.filter.HttpServerFilter;
import org.apache.servicecomb.common.rest.locator.OperationLocator;
import org.apache.servicecomb.common.rest.locator.ServicePathManager;
import org.apache.servicecomb.common.rest.locator.TestPathSchema;
import org.apache.servicecomb.config.ConfigUtil;
import org.apache.servicecomb.core.SCBEngine;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.core.bootstrap.SCBBootstrap;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.apache.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;
import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
import org.apache.servicecomb.registry.api.registry.Microservice;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

public class TestRestProducerInvocation {

  Transport transport = Mockito.mock(Transport.class);

  HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);

  HttpServletResponseEx responseEx = Mockito.mock(HttpServletResponseEx.class);

  RestProducerInvocation restProducerInvocation;

  Throwable throwableOfSendFailResponse;

  boolean scheduleInvocation;

  static List<HttpServerFilter> httpServerFilters = SPIServiceUtils.getSortedService(HttpServerFilter.class);

  static SCBEngine scbEngine;

  static OperationMeta operationMeta;

  static RestOperationMeta restOperationMeta;

  static MicroserviceMeta microserviceMeta;

  @BeforeClass
  public static void classSetup() {
    ConfigUtil.installDynamicConfig();
    scbEngine = SCBBootstrap.createSCBEngineForTest()
        .addProducerMeta("sid1", new TestPathSchema())
        .run();
    operationMeta = scbEngine.getProducerMicroserviceMeta().operationMetas().get("test.sid1.dynamicId");
    restOperationMeta = RestMetaUtils.getRestOperationMeta(operationMeta);
    microserviceMeta = operationMeta.getMicroserviceMeta();
  }

  @AfterClass
  public static void classTeardown() {
    scbEngine.destroy();
    ArchaiusUtils.resetConfig();
  }

  private void initRestProducerInvocation() {
    restProducerInvocation.transport = transport;
    restProducerInvocation.requestEx = requestEx;
    restProducerInvocation.responseEx = responseEx;
    restProducerInvocation.restOperationMeta = restOperationMeta;
    restProducerInvocation.httpServerFilters = httpServerFilters;
  }

  @Test
  public void invokeSendFail() {
    InvocationException expected = new InvocationException(javax.ws.rs.core.Response.Status.BAD_REQUEST, "test");
    restProducerInvocation = Mockito.spy(new RestProducerInvocation());
    Mockito.doThrow(expected).when(restProducerInvocation).findRestOperation();
    Mockito.doAnswer(invocationOnMock -> {
      throwableOfSendFailResponse = expected;
      return null;
    }).when(restProducerInvocation).sendFailResponse(Mockito.any());
    Mockito.doThrow(new IllegalStateException("must not invoke scheduleInvocation")).when(restProducerInvocation).scheduleInvocation();


    restProducerInvocation.invoke(transport, requestEx, responseEx, httpServerFilters);

    Assertions.assertSame(expected, throwableOfSendFailResponse);
  }

  @Test
  public void invokeNormal() {
    restProducerInvocation = Mockito.spy(new RestProducerInvocation());
    Mockito.doAnswer(invocationOnMock -> {
      restProducerInvocation.restOperationMeta = restOperationMeta;
      return null;
    }).when(restProducerInvocation).findRestOperation();
    Mockito.doAnswer(invocationOnMock -> {
      scheduleInvocation = true;
      return null;
    }).when(restProducerInvocation).scheduleInvocation();

    requestEx = new AbstractHttpServletRequest() {
    };
    restProducerInvocation.invoke(transport, requestEx, responseEx, httpServerFilters);

    Assertions.assertTrue(scheduleInvocation);
    Assertions.assertSame(requestEx, requestEx.getAttribute(RestConst.REST_REQUEST));
  }

  @Test
  public void findRestOperationNameFromRegistry() {
    Microservice microservice = new Microservice();
    microservice.setServiceName("ms");

    try (MockedStatic<ServicePathManager> managerMockedStatic = Mockito.mockStatic(ServicePathManager.class)){
      managerMockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(null);
      restProducerInvocation = new RestProducerInvocation();
      initRestProducerInvocation();

      Exception exception = Assertions.assertThrows(Exception.class,
              () -> restProducerInvocation.findRestOperation());
      Assertions.assertTrue(exception.getMessage().contains("[message=Not Found]"));
    }
  }

  @Test
  public void findRestOperationNormal() {
    requestEx = new AbstractHttpServletRequest() {
      @Override
      public String getRequestURI() {
        return "/path";
      }

      @Override
      public String getMethod() {
        return "GET";
      }

      @Override
      public String getHeader(String name) {
        return "ms";
      }
    };
    Map<String, String> pathVars = new HashMap<>();
    try (MockedStatic<ServicePathManager> managerMockedStatic = Mockito.mockStatic(ServicePathManager.class)){
      ServicePathManager servicePathManager = Mockito.mock(ServicePathManager.class);
      OperationLocator locator = Mockito.mock(OperationLocator.class);
      managerMockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(servicePathManager);
      Mockito.when(servicePathManager.producerLocateOperation(Mockito.any(), Mockito.any())).thenReturn(locator);
      Mockito.when(locator.getPathVarMap()).thenReturn(pathVars);
      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);
      restProducerInvocation = new RestProducerInvocation();
      initRestProducerInvocation();

      restProducerInvocation.findRestOperation();
      Assertions.assertSame(restOperationMeta, restProducerInvocation.restOperationMeta);
      Assertions.assertSame(pathVars, requestEx.getAttribute(RestConst.PATH_PARAMETERS));
    }
  }
}
