/*
 * 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.demo.springmvc.server;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response.Status;

import org.apache.commons.io.IOUtils;
import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import org.apache.servicecomb.core.BootListener;
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.demo.EmptyObject;
import org.apache.servicecomb.demo.Generic;
import org.apache.servicecomb.demo.compute.GenericParam;
import org.apache.servicecomb.demo.compute.GenericParamExtended;
import org.apache.servicecomb.demo.compute.GenericParamWithJsonIgnore;
import org.apache.servicecomb.demo.compute.Person;
import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;
import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;
import org.apache.servicecomb.demo.jaxbbean.JAXBPerson;
import org.apache.servicecomb.demo.server.User;
import org.apache.servicecomb.demo.springmvc.decoderesponse.DecodeTestResponse;
import org.apache.servicecomb.foundation.common.Holder;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.metrics.core.MetricsBootListener;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;
import org.apache.servicecomb.swagger.extend.annotations.ResponseHeaders;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ResponseHeader;
import io.vertx.core.json.JsonObject;

@RestSchema(schemaId = "codeFirst")
@RequestMapping(path = "/codeFirstSpringmvc", produces = MediaType.APPLICATION_JSON_VALUE)
public class CodeFirstSpringmvc {
  private static final Logger LOGGER = LoggerFactory.getLogger(CodeFirstSpringmvc.class);

  private AtomicInteger invocationCounter = new AtomicInteger(0);

  private String _fileUpload(MultipartFile file1, Part file2) {
    try (InputStream is1 = file1.getInputStream(); InputStream is2 = file2.getInputStream()) {
      String content1 = IOUtils.toString(is1, StandardCharsets.UTF_8);
      String content2 = IOUtils.toString(is2, StandardCharsets.UTF_8);
      return String.format("%s:%s:%s\n"
              + "%s:%s:%s",
          file1.getOriginalFilename(),
          file1.getContentType(),
          content1,
          file2.getSubmittedFileName(),
          file2.getContentType(),
          content2);
    } catch (IOException e) {
      throw new IllegalArgumentException(e);
    }
  }

  @GetMapping(path = "/retrySuccess")
  public int retrySuccess(@RequestParam("a") int a, @RequestParam("b") int b) {
    if (invocationCounter.getAndIncrement() % 3 != 0) {
      throw new InvocationException(Status.SERVICE_UNAVAILABLE, "try again later.");
    }
    return a + b;
  }

  @PostMapping(path = "/upload1", produces = MediaType.TEXT_PLAIN_VALUE)
  public String fileUpload1(@RequestPart(name = "file1") MultipartFile file1) throws IOException {
    try (InputStream is = file1.getInputStream()) {
      return IOUtils.toString(is, StandardCharsets.UTF_8);
    }
  }

  @PostMapping(path = "/upload", produces = MediaType.TEXT_PLAIN_VALUE)
  public String fileUpload(@RequestPart(name = "file1") MultipartFile file1,
      @RequestPart(name = "someFile") Part file2) {
    return _fileUpload(file1, file2);
  }

  @ResponseHeaders({@ResponseHeader(name = "h1", response = String.class),
      @ResponseHeader(name = "h2", response = String.class)})
  @RequestMapping(path = "/responseEntity", method = RequestMethod.POST)
  public ResponseEntity<Date> responseEntity(InvocationContext c1, @RequestAttribute("date") Date date) {
    HttpHeaders headers = new HttpHeaders();
    headers.add("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE));

    InvocationContext c2 = ContextUtils.getInvocationContext();
    headers.add("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE));

    return new ResponseEntity<>(date, headers, HttpStatus.ACCEPTED);
  }

  @ResponseHeaders({@ResponseHeader(name = "h1", response = String.class),
      @ResponseHeader(name = "h2", response = String.class)})
  @RequestMapping(path = "/responseEntity", method = RequestMethod.PATCH)
  public ResponseEntity<Date> responseEntityPATCH(InvocationContext c1, @RequestAttribute("date") Date date) {
    return responseEntity(c1, date);
  }

  // This definition is not correct, response type is not
  // same as the actual one. May be not support in future.
  @ApiResponse(code = 200, response = User.class, message = "")
  @ResponseHeaders({@ResponseHeader(name = "h1", response = String.class),
      @ResponseHeader(name = "h2", response = String.class)})
  @RequestMapping(path = "/cseResponse", method = RequestMethod.GET)
  public Response cseResponse(InvocationContext c1) {
    Response response = Response.createSuccess(Status.ACCEPTED, new User());
    response.addHeader("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE));

    InvocationContext c2 = ContextUtils.getInvocationContext();
    response.addHeader("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE));

    return response;
  }

  // This definition is correct, but not supported by highway.
  // highway do not support define code other than 200
  @ApiResponse(code = 202, response = User.class, message = "")
  @ResponseHeaders({@ResponseHeader(name = "h1", response = String.class),
      @ResponseHeader(name = "h2", response = String.class)})
  @RequestMapping(path = "/cseResponseCorrect", method = RequestMethod.GET)
  public Response cseResponseCorrect(InvocationContext c1) {
    Response response = Response.createSuccess(Status.ACCEPTED, new User());
    response.addHeader("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE));

    InvocationContext c2 = ContextUtils.getInvocationContext();
    response.addHeader("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE));

    return response;
  }

  @PostMapping(path = "/testUserMap")
  public Map<String, User> testUserMap(@RequestBody Map<String, User> userMap) {
    return userMap;
  }

  @RequestMapping(path = "/textPlain", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN_VALUE)
  public String textPlain(@RequestBody String body) {
    return body;
  }

  @RequestMapping(path = "/appXml", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
  public JAXBPerson appXml(@RequestBody JAXBPerson person) {
    return person;
  }

  @RequestMapping(path = "/bytes", method = RequestMethod.POST)
  public byte[] bytes(@RequestBody byte[] input) {
    input[0] = (byte) (input[0] + 1);
    return input;
  }

  @RequestMapping(path = "/addDate", method = RequestMethod.POST)
  public Date addDate(@RequestAttribute("date") Date date, @QueryParam("seconds") long seconds) {
    return new Date(date.getTime() + seconds * 1000);
  }

  // this should be ignored as it's hidden
  @ApiOperation(value = "", hidden = true, httpMethod = "POST")
  public int add(@RequestParam("a") int a) {
    return a;
  }

  @RequestMapping(path = "/add", method = RequestMethod.POST)
  public int add(@RequestAttribute("a") int a, @RequestAttribute("b") int b) {
    return a + b;
  }

  @GetMapping(path = "/reduce")
  @ApiImplicitParams({@ApiImplicitParam(name = "a", dataType = "integer", format = "int32", paramType = "query")})
  public int reduce(HttpServletRequest request, @CookieValue(name = "b") int b) {
    int a = Integer.parseInt(request.getParameter("a"));
    return a - b;
  }

  @RequestMapping(path = "/sayhello", method = RequestMethod.POST)
  public Person sayHello(@RequestBody Person user) {
    user.setName("hello " + user.getName());
    return user;
  }

  @SuppressWarnings("unchecked")
  @RequestMapping(path = "/testrawjson", method = RequestMethod.POST)
  public String testRawJsonString(String jsonInput) {
    Map<String, String> person;
    try {
      person = RestObjectMapperFactory.getRestObjectMapper().readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
    return "hello " + person.get("name");
  }

  @RequestMapping(path = "/saysomething", method = RequestMethod.POST)
  public String saySomething(@RequestHeader(name = "prefix") String prefix, @RequestBody Person user) {
    return prefix + " " + user.getName();
  }

  @PutMapping(path = "/sayhi/{name}")
  public String sayHi(@PathVariable(name = "name") String name) {
    ContextUtils.getInvocationContext().setStatus(202);
    return name + " sayhi";
  }

  @RequestMapping(path = "/sayhi/compressed/{name}/v2", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
  public String sayHiForCompressed(@PathVariable(name = "name") String name) {
    String bigText =
        "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,"
            + "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,"
            + "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,"
            + "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,"
            + "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,"
            + "This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text!";
    return name + " sayhi compressed:" + bigText;
  }

  @RequestMapping(path = "/sayhi/{name}/v2", method = RequestMethod.PUT)
  public String sayHi2(@PathVariable(name = "name") String name) {
    return name + " sayhi 2";
  }

  @RequestMapping(path = "/istrue", method = RequestMethod.GET)
  public boolean isTrue() {
    return true;
  }

  @DeleteMapping(path = "/addstring", produces = MediaType.TEXT_PLAIN_VALUE)
  public String addString(@RequestParam(name = "s") List<String> s) {
    StringBuilder result = new StringBuilder();
    for (String x : s) {
      result.append(x);
    }
    return result.toString();
  }

  // Using 490, 590 error code, the response type should be CommonExceptionData. Or we need
  // complex ExceptionConverters to deal with exceptions thrown by Hanlders, etc.
  @RequestMapping(path = "/fallback/returnnull/{name}", method = RequestMethod.GET)
  @ApiResponses(value = {@ApiResponse(code = 200, response = String.class, message = "xxx"),
      @ApiResponse(code = 490, response = CommonExceptionData.class, message = "xxx")})
  public String fallbackReturnNull(@PathVariable(name = "name") String name) {
    if ("throwexception".equals(name)) {
      throw new InvocationException(490, "490", new CommonExceptionData("xxx"));
    }
    return name;
  }

  @RequestMapping(path = "/fallback/throwexception/{name}", method = RequestMethod.GET)
  @ApiResponses(value = {@ApiResponse(code = 200, response = String.class, message = "xxx"),
      @ApiResponse(code = 490, response = CommonExceptionData.class, message = "xxx")})
  public String fallbackThrowException(@PathVariable(name = "name") String name) {
    if ("throwexception".equals(name)) {
      throw new InvocationException(490, "490", new CommonExceptionData("xxx"));
    }
    return name;
  }

  @RequestMapping(path = "/fallback/fromcache/{name}", method = RequestMethod.GET)
  @ApiResponses(value = {@ApiResponse(code = 200, response = String.class, message = "xxx"),
      @ApiResponse(code = 490, response = CommonExceptionData.class, message = "xxx")})
  public String fallbackFromCache(@PathVariable(name = "name") String name) {
    if ("throwexception".equals(name)) {
      throw new InvocationException(490, "490", new CommonExceptionData("xxx"));
    }
    return name;
  }

  @RequestMapping(path = "/fallback/force/{name}", method = RequestMethod.GET)
  @ApiResponses(value = {@ApiResponse(code = 200, response = String.class, message = "xxx"),
      @ApiResponse(code = 490, response = CommonExceptionData.class, message = "xxx")})
  public String fallbackForce(@PathVariable(name = "name") String name) {
    if ("throwexception".equals(name)) {
      throw new InvocationException(490, "490", new CommonExceptionData("xxx"));
    }
    return name;
  }

  public enum NameType {
    abc,
    def
  }

  @RequestMapping(path = "/testenum/{name}", method = RequestMethod.GET)
  @ApiResponses(value = {@ApiResponse(code = 200, response = String.class, message = "200 normal"),
      @ApiResponse(code = 490, response = CommonExceptionData.class, message = "490 exception")})
  public String testEnum(@RequestParam(name = "username") String username,
      @PathVariable(value = "name") NameType nameType) {
    return nameType.toString();
  }

  @RequestMapping(method = RequestMethod.POST, value = "/ignore")
  @ResponseBody
  public OutputModelForTestIgnore testModelWithIgnoreField(@RequestBody InputModelForTestIgnore input) {
    return new OutputModelForTestIgnore("output_id", input.getInputId(), input.getContent(), input.getInputObject(),
        input.getInputJsonObject(), input.getInputIgnoreInterface(),
        new Person("outputSomeone"), new JsonObject("{\"OutputJsonKey\" : \"OutputJsonValue\"}"), () -> {
    });
  }

  @SuppressWarnings("unchecked")
  @RequestMapping(method = RequestMethod.POST, value = "/rawJsonAnnotation")
  @ResponseBody
  public String testRawJsonAnnotation(@RawJsonRequestBody String jsonInput) {
    Map<String, String> person;
    try {
      person = RestObjectMapperFactory.getRestObjectMapper().readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
    return "hello " + person.get("name");
  }

  @PostMapping(path = "/testform")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "form1", dataType = "string", paramType = "form", value = "a required form param",
          required = true),
      @ApiImplicitParam(name = "form2", dataType = "string", paramType = "form", value = "an optional form param",
          required = false)})
  public String testform(HttpServletRequest request) {
    String form1 = request.getParameter("form1");
    String form2 = request.getParameter("form2");
    Assert.notNull(form1, "from1 is null");
    return form1 + form2;
  }

  MetricsBootListener metricsBootListener = SPIServiceUtils
      .getTargetService(BootListener.class, MetricsBootListener.class);

  //Only for Prometheus integration test
  @RequestMapping(path = "/prometheusForTest", method = RequestMethod.GET)
  public String prometheusForTest() {
    // just for test, this makes client always can got latest metrics
    metricsBootListener.getMetricsBootstrap().pollMeters();

    RestTemplate defaultRestTemplate = new RestTemplate();
    return defaultRestTemplate.getForObject("http://localhost:9696/metrics", String.class);
  }

  @GetMapping(path = "/traceId")
  public String getTraceId() {
    return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
  }

  @PostMapping(path = "/emptyObject")
  public EmptyObject testEmpty(@RequestBody EmptyObject input) {
    return input;
  }

  @PostMapping(path = "/object")
  public Object testObject(@RequestBody Object input) {
    return input;
  }

  @PostMapping(path = "/mapObject")
  public Map<String, Object> testMapObject(@RequestBody Map<String, Object> input) {
    return input;
  }

  @PostMapping(path = "/listObject")
  public List<Object> testListObject(@RequestBody List<Object> input) {
    return input;
  }

  @PostMapping(path = "/holderObject")
  public Holder<Object> testHolderObject(@RequestBody Holder<Object> input) {
    return input;
  }

  @PostMapping(path = "/holderUser")
  public Holder<User> testHolderUser(@RequestBody Holder<User> input) {
    Assert.isInstanceOf(Holder.class, input);
    Assert.isInstanceOf(User.class, input.value);
    return input;
  }

  @PostMapping(path = "/genericUser")
  public Generic<User> testGenericUser(@RequestBody Generic<User> input) {
    Assert.isInstanceOf(Generic.class, input);
    Assert.isInstanceOf(User.class, input.value);
    return input;
  }

  @PostMapping(path = "/genericLong")
  public Generic<Long> testGenericLong(@RequestBody Generic<Long> input) {
    Assert.isInstanceOf(Generic.class, input);
    Assert.isInstanceOf(Long.class, input.value);
    return input;
  }

  @PostMapping(path = "/genericDate")
  public Generic<Date> testGenericDate(@RequestBody Generic<Date> input) {
    Assert.isInstanceOf(Generic.class, input);
    Assert.isInstanceOf(Date.class, input.value);
    System.out.println(input.value);
    return input;
  }

  @PostMapping(path = "/genericEnum")
  public Generic<HttpStatus> testGenericEnum(@RequestBody Generic<HttpStatus> input) {
    Assert.isInstanceOf(Generic.class, input);
    Assert.isInstanceOf(HttpStatus.class, input.value);
    return input;
  }

  @PostMapping(path = "/genericGenericUser")
  public Generic<Generic<User>> testGenericGenericUser(@RequestBody Generic<Generic<User>> input) {
    Assert.isInstanceOf(Generic.class, input);
    Assert.isInstanceOf(Generic.class, input.value);
    Assert.isInstanceOf(User.class, input.value.value);
    return input;
  }

  private boolean testvoidInRPCSuccess = false;

  @GetMapping(path = "/testvoidInRPC")
  public void testvoidInRPC() {
    LOGGER.info("testvoidInRPC() is called!");
    testvoidInRPCSuccess = true;
  }

  private boolean testVoidInRPCSuccess = false;

  @GetMapping(path = "/testVoidInRPC")
  public Void testVoidInRPC() {
    LOGGER.info("testVoidInRPC() is called!");
    testVoidInRPCSuccess = true;
    return null;
  }

  private boolean testvoidInRestTemplateSuccess = false;

  @GetMapping(path = "/testvoidInRestTemplate")
  public void testvoidInRestTemplate() {
    LOGGER.info("testvoidInRestTemplate() is called!");
    testvoidInRestTemplateSuccess = true;
  }

  private boolean testVoidInRestTemplateSuccess = false;

  @GetMapping(path = "/testVoidInRestTemplate")
  public Void testVoidInRestTemplate() {
    LOGGER.info("testVoidInRestTemplate() is called!");
    testVoidInRestTemplateSuccess = true;
    return null;
  }

  @GetMapping(path = "/checkVoidResult")
  public boolean checkVoidResult() {
    LOGGER.info("checkVoidResult() is called!");
    return testvoidInRPCSuccess && testVoidInRPCSuccess && testvoidInRestTemplateSuccess
        && testVoidInRestTemplateSuccess;
  }

  /**
   * Simple query object test, users can use it mixed with InvocationContext and plain query param, RequestBody
   */
  @PostMapping(path = "/checkQueryObject")
  public String checkQueryObject(Person person, @RequestParam(name = "otherName") String otherName,
      InvocationContext invocationContext, @RequestBody Person requestBody) {
    LOGGER.info("checkQueryObject() is called!");
    return "invocationContext_is_null=" + (null == invocationContext) + ",person="
        + person + ",otherName=" + otherName + ",name=" + person.getName() + ",requestBody=" + requestBody;
  }

  /**
   * For the nesting object params, including the generic params whose generic field is an object,
   * the inner object field is not supported.
   */
  @PutMapping(path = "/checkQueryGenericObject")
  public String checkQueryGenericObject(@RequestBody GenericParam<Person> requestBody,
      GenericParamWithJsonIgnore<Person> generic) {
    LOGGER.info("checkQueryGenericObject() is called!");
    return "str=" + generic.getStr() + ",generic=" + generic + ",requestBody=" + requestBody;
  }

  /**
   * If the generic field is simple type, it's supported to be deserialized.
   * The same for those simple type field inherited from the parent class.
   */
  @PutMapping(path = "/checkQueryGenericString")
  public String checkQueryGenericString(@RequestBody GenericParam<Person> requestBody,
      GenericParamExtended<String> generic) {
    LOGGER.info("checkQueryGenericObject() is called!");
    return "str=" + generic.getStr() + ",generic=" + generic + ",requestBody=" + requestBody;
  }

  @GetMapping(path = "/testDelay")
  public String testDelay() {
    LOGGER.info("testDelay() is called!");
    return "OK";
  }

  @GetMapping(path = "/testAbort")
  public String testAbort() {
    LOGGER.info("testAbort() is called!");
    return "OK";
  }

  @GetMapping(path = "/testDecodeResponseError")
  public DecodeTestResponse testDecodeResponseError() {
    DecodeTestResponse response = new DecodeTestResponse();
    response.setContent("returnOK");
    return response;
  }

  @RequestMapping(path = "/testDefaultGetApiExample")
  public void testDefaultGetApiExample() {
    LOGGER.info("testDefaultGetApiExample() is called!");
  }
}
