/*
 * 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.core.filter.impl;

import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.exception.Exceptions;
import org.apache.servicecomb.core.filter.FilterNode;
import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;
import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
import org.apache.servicecomb.swagger.invocation.context.InvocationContext;
import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.junit.Test;

import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import mockit.Verifications;

public class ProducerOperationFilterTest {
  ProducerOperationFilter filter = new ProducerOperationFilter();

  @Injectable
  Invocation invocation;

  @Mocked
  SwaggerProducerOperation producerOperation;

  static InvocationContext threadInvocationContext;

  public static class Controller {
    public void sync() {
      threadInvocationContext = ContextUtils.getInvocationContext();
    }

    public void syncException() {
      throw new RuntimeExceptionWithoutStackTrace("syncException");
    }

    public CompletableFuture<Void> async() {
      threadInvocationContext = ContextUtils.getInvocationContext();
      return CompletableFuture.completedFuture(null);
    }

    public CompletableFuture<Void> asyncException() {
      throw new RuntimeExceptionWithoutStackTrace("asyncException");
    }
  }

  @Test
  public void should_record_invocation_trace_time() throws NoSuchMethodException {
    setInvokeSyncMethod();
    filter.onFilter(invocation, FilterNode.EMPTY);

    new Verifications() {
      {
        invocation.onBusinessMethodStart();
        times = 1;

        invocation.onBusinessMethodFinish();
        times = 1;

        invocation.onBusinessFinish();
        times = 1;
      }
    };
  }

  private void setInvokeMethod(String name) throws NoSuchMethodException {
    Controller instance = new Controller();
    Method method = instance.getClass().getMethod(name);
    new Expectations() {
      {
        producerOperation.getProducerInstance();
        result = instance;

        producerOperation.getProducerMethod();
        result = method;
      }
    };
  }

  private void setInvokeSyncMethod() throws NoSuchMethodException {
    setInvokeMethod("sync");
  }

  private void setInvokeAsyncMethod() throws NoSuchMethodException {
    setInvokeMethod("async");
  }

  @Test
  public void should_provide_thread_local_invocation_context_for_sync_method() throws NoSuchMethodException {
    setInvokeSyncMethod();

    filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(threadInvocationContext).isSameAs(invocation);
  }

  @Test
  public void should_clear_thread_local_invocation_context_after_sync_method() throws NoSuchMethodException {
    setInvokeSyncMethod();

    filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(ContextUtils.getInvocationContext()).isNull();
  }

  @Test
  public void should_catch_sync_business_exception() throws NoSuchMethodException {
    setInvokeMethod("syncException");

    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(future)
            .failsWithin(Duration.ofSeconds(1))
            .withThrowableOfType(ExecutionException.class)
            .withCauseExactlyInstanceOf(RuntimeExceptionWithoutStackTrace.class)
            .withMessage("org.apache.servicecomb.foundation.test.scaffolding.exception" +
                    ".RuntimeExceptionWithoutStackTrace: syncException");
  }

  @Test
  public void should_provide_thread_local_invocation_context_for_async_method() throws NoSuchMethodException {
    setInvokeAsyncMethod();

    filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(threadInvocationContext).isSameAs(invocation);
  }

  @Test
  public void should_clear_thread_local_invocation_context_after_async_method() throws NoSuchMethodException {
    setInvokeAsyncMethod();

    filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(ContextUtils.getInvocationContext()).isNull();
  }

  @Test
  public void should_catch_async_business_exception() throws NoSuchMethodException {
    setInvokeMethod("asyncException");

    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(future)
            .failsWithin(Duration.ofSeconds(1))
            .withThrowableOfType(ExecutionException.class)
            .withCauseExactlyInstanceOf(RuntimeExceptionWithoutStackTrace.class)
            .withMessage("org.apache.servicecomb.foundation.test.scaffolding" +
                    ".exception.RuntimeExceptionWithoutStackTrace: asyncException");
  }

  @Test
  public void should_unify_IllegalArgumentException_message_when_convert_exception() throws NoSuchMethodException {
    setInvokeSyncMethod();
    new Expectations() {
      {
        invocation.toProducerArguments();
        result = new Object[] {1};
      }
    };
    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);

    assertThat(future)
            .failsWithin(Duration.ofSeconds(1))
            .withThrowableOfType(ExecutionException.class)
            .withCauseExactlyInstanceOf(IllegalArgumentException.class)
            .withMessage("java.lang.IllegalArgumentException: wrong number of arguments");

    InvocationException throwable = Exceptions
        .convert(invocation, catchThrowable(future::get), INTERNAL_SERVER_ERROR);
    assertThat(throwable).hasCauseInstanceOf(IllegalArgumentException.class);
    CommonExceptionData data = (CommonExceptionData) throwable.getErrorData();
    assertThat(data.getMessage()).isEqualTo("Parameters not valid or types not match.");
  }
}
