/*
 * 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.codec.param;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;

import io.vertx.core.buffer.impl.BufferImpl;
import org.apache.servicecomb.common.rest.RestConst;
import org.apache.servicecomb.common.rest.codec.RestClientRequest;
import org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.BodyProcessor;
import org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.RawJsonBodyProcessor;
import org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;
import org.junit.jupiter.api.Assertions;
import org.junit.Before;
import org.junit.Test;

import com.fasterxml.jackson.databind.type.TypeFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.vertx.core.MultiMap;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.impl.headers.HeadersMultiMap;
import org.mockito.Mockito;


public class TestBodyProcessor {

  HttpServletRequest request = Mockito.mock(HttpServletRequest.class);

  MultiMap headers;

  RestClientRequest clientRequest = Mockito.mock(RestClientRequest.class);

  ParamValueProcessor processor;

  ByteBuf inputBodyByteBuf = Unpooled.buffer();

  BufferInputStream inputStream = new BufferInputStream(inputBodyByteBuf);

  Buffer outputBodyBuffer;

  String value;

  private void createProcessor(Class<?> type) {
    processor = new BodyProcessor(TypeFactory.defaultInstance().constructType(type), type.equals(String.class), true);
  }

  private void createRawJsonProcessor() {
    processor = new RawJsonBodyProcessor(TypeFactory.defaultInstance().constructType(String.class), true, true);
  }

  private void createClientRequest() {
    Mockito.doAnswer(invocation -> {
      headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
      return null;
    }).when(clientRequest).putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);


    Mockito.when(clientRequest.getHeaders()).thenReturn(headers);
  }

  private void initInputStream() throws IOException {
    Mockito.when(request.getInputStream()).thenReturn(inputStream);
  }

  private void setupGetValue(Class<?> type) throws IOException {
    createProcessor(type);
    initInputStream();
  }

  @Before
  public void before() {
    headers = new HeadersMultiMap();
    value = "value";
  }

  @Test
  public void testGetValueHaveAttr() throws Exception {
    int body = 10;
    createProcessor(String.class);
    Mockito.when(request.getAttribute(RestConst.BODY_PARAMETER)).thenReturn(body);

    Object result = processor.getValue(request);
    Assertions.assertEquals("10", result);
  }

  @Test
  public void testGetValueNoAttrNoStream() throws Exception {
    createProcessor(String.class);
    Mockito.when(request.getInputStream()).thenReturn(null);
    Object result = processor.getValue(request);
    Assertions.assertNull(result);
  }

  @Test
  public void testGetValueTextPlain() throws Exception {
    setupGetValue(String.class);
    inputBodyByteBuf.writeCharSequence("abc", StandardCharsets.UTF_8);

    Mockito.when(request.getContentType()).thenReturn(MediaType.TEXT_PLAIN);

    Assertions.assertEquals("abc", processor.getValue(request));
  }

  @Test
  public void testGetValueContextTypeJson() throws Exception {
    setupGetValue(Integer.class);
    inputBodyByteBuf.writeCharSequence("\"1\"", StandardCharsets.UTF_8);

    Mockito.when(request.getContentType()).thenReturn(MediaType.APPLICATION_JSON);

    Assertions.assertEquals(1, processor.getValue(request));
  }

  @Test
  public void testGetValueDefaultJson() throws Exception {
    setupGetValue(Integer.class);
    inputBodyByteBuf.writeCharSequence("\"1\"", StandardCharsets.UTF_8);

    Assertions.assertEquals(1, processor.getValue(request));
  }

  @Test
  public void testSetValue() throws Exception {
    createClientRequest();
    createProcessor(String.class);

    Mockito.when(clientRequest.getHeaders()).thenReturn(headers);
    ParamValueProcessor spy = Mockito.spy(processor);
    Mockito.doAnswer(invocation -> {
      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));
      return null;
    }).when(spy).setValue(clientRequest, value);

    spy.setValue(clientRequest, value);
    processor.setValue(clientRequest, value);
    Assertions.assertEquals(MediaType.APPLICATION_JSON, headers.get(HttpHeaders.CONTENT_TYPE));
    Assertions.assertEquals(value, outputBodyBuffer.toString());
  }

  @Test
  public void testSetValueTextPlain() throws Exception {
    createClientRequest();
    createProcessor(String.class);
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);

    ParamValueProcessor spy = Mockito.spy(processor);
    Mockito.doAnswer(invocation -> {
      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));
      return null;
    }).when(spy).setValue(clientRequest, value);

    spy.setValue(clientRequest, value);
    processor.setValue(clientRequest, value);
    Assertions.assertEquals(MediaType.TEXT_PLAIN, headers.get(HttpHeaders.CONTENT_TYPE));
    Assertions.assertEquals(value, outputBodyBuffer.toString());
  }

  @Test
  public void testSetValueTextPlainTypeMismatch() {
    createClientRequest();
    createProcessor(String.class);
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);

    try {
      processor.setValue(clientRequest, new Date());
      Assertions.fail("an exception is expected!");
    } catch (Exception e) {
      Assertions.assertEquals(IllegalArgumentException.class, e.getClass());
      Assertions.assertEquals("Content-Type is text/plain while arg type is not String", e.getMessage());
    }
  }

  @Test
  public void testGetParameterPath() {
    createProcessor(String.class);
    Assertions.assertEquals("", processor.getParameterPath());
  }

  @Test
  public void testGetProcessorType() {
    createProcessor(String.class);
    Assertions.assertEquals("body", processor.getProcessorType());
  }

  @Test
  public void testGetValueRawJson() throws Exception {
    createRawJsonProcessor();
    initInputStream();
    inputBodyByteBuf.writeCharSequence("\"1\"", StandardCharsets.UTF_8);

    Assertions.assertEquals("\"1\"", processor.getValue(request));
  }

  @Test
  public void testGetValueRawJsonHaveAttr() throws Exception {
    int body = 10;
    createRawJsonProcessor();
    Mockito.when(request.getAttribute(RestConst.BODY_PARAMETER)).thenReturn(body);

    Object result = processor.getValue(request);
    Assertions.assertEquals("10", result);
  }

  @Test
  public void testGetValueRawJsonNoAttrNoStream() throws Exception {
    createRawJsonProcessor();
    Mockito.when(request.getInputStream()).thenReturn(null);

    Object result = processor.getValue(request);
    Assertions.assertNull(result);
  }

  @Test
  public void testSetValueRawJson() throws Exception {
    createClientRequest();
    createRawJsonProcessor();

    ParamValueProcessor spy = Mockito.spy(processor);
    Mockito.doAnswer(invocation -> {
      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));
      return null;
    }).when(spy).setValue(clientRequest, value);
    spy.setValue(clientRequest, value);
    processor.setValue(clientRequest, value);
    Assertions.assertEquals(MediaType.APPLICATION_JSON, headers.get(HttpHeaders.CONTENT_TYPE));
    Assertions.assertEquals("value", outputBodyBuffer.toString());
  }

  static class BodyModel {
    public String name;

    public int age;
  }

  @Test
  public void convertFromFormData() throws Exception {
    createProcessor(BodyModel.class);
    Map<String, String[]> parameterMap = new HashMap<>();
    parameterMap.put("name", new String[] {"n"});
    parameterMap.put("age", new String[] {"10"});
    Mockito.when(request.getParameterMap()).thenReturn(parameterMap);
    Mockito.when(request.getContentType()).thenReturn(MediaType.MULTIPART_FORM_DATA + ";utf-8");

    BodyModel bm = (BodyModel) processor.getValue(request);
    Assertions.assertEquals("n", bm.name);
    Assertions.assertEquals(10, bm.age);
  }

  @Test
  public void convertFromUrlencoded() throws Exception {
    createProcessor(BodyModel.class);
    Map<String, String[]> parameterMap = new HashMap<>();
    parameterMap.put("name", new String[] {"n"});
    parameterMap.put("age", new String[] {"10"});
    Mockito.when(request.getParameterMap()).thenReturn(parameterMap);
    Mockito.when(request.getContentType()).thenReturn(MediaType.APPLICATION_FORM_URLENCODED + ";utf-8");

    BodyModel bm = (BodyModel) processor.getValue(request);
    Assertions.assertEquals("n", bm.name);
    Assertions.assertEquals(10, bm.age);
  }
}
