package com.mmc.pms.controller;

import com.mmc.pms.config.SwaggerConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.ResponseEntity;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.stereotype.Controller;
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.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.annotations.ApiIgnore;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.spring.web.json.Json;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger.web.ApiResourceController;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
import springfox.documentation.swagger2.web.Swagger2ControllerWebMvc;
import springfox.documentation.swagger2.web.WebMvcSwaggerTransformationFilter;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
 * @Author small
 * @Date 2023/5/15 10:30
 * @Version 1.0
 */
@Controller
@ApiIgnore
@RequestMapping(SwaggerConfig.DEFAULT_PATH)
public class SwaggerResourceController implements InitializingBean {
    private final ApiResourceController apiResourceController;
    private final DocumentationCache documentationCache;
    private final ServiceModelToSwagger2Mapper mapper;
    private final JsonSerializer jsonSerializer;
    private final PluginRegistry<WebMvcSwaggerTransformationFilter, DocumentationType>
            transformations;
    private static final String HAL_MEDIA_TYPE = "application/hal+json";
    private Swagger2ControllerWebMvc swagger2ControllerWebMvc;

    public SwaggerResourceController(
            ApiResourceController apiResourceController,
            DocumentationCache documentationCache,
            ServiceModelToSwagger2Mapper mapper,
            JsonSerializer jsonSerializer,
            PluginRegistry<WebMvcSwaggerTransformationFilter, DocumentationType> transformations) {
        this.apiResourceController = apiResourceController;
        this.documentationCache = documentationCache;
        this.mapper = mapper;
        this.jsonSerializer = jsonSerializer;
        this.transformations = transformations;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        swagger2ControllerWebMvc =
                new Swagger2ControllerWebMvc(documentationCache, mapper, jsonSerializer, transformations);
    }

    /**
     * Swagger API首页地址
     *
     * @return 首页地址
     */
    @RequestMapping
    public ModelAndView index() {
        return new ModelAndView("redirect:" + SwaggerConfig.DEFAULT_PATH + "/doc.html");
    }

    @RequestMapping("/swagger-resources/configuration/security")
    @ResponseBody
    public ResponseEntity<SecurityConfiguration> securityConfiguration() {
        return apiResourceController.securityConfiguration();
    }

    @RequestMapping("/swagger-resources/configuration/ui")
    @ResponseBody
    public ResponseEntity<UiConfiguration> uiConfiguration() {
        return apiResourceController.uiConfiguration();
    }

    @RequestMapping("/swagger-resources")
    @ResponseBody
    public ResponseEntity<List<SwaggerResource>> swaggerResources() {
        return apiResourceController.swaggerResources();
    }

    @RequestMapping(
            value = "/v2/api-docs",
            method = RequestMethod.GET,
            produces = {APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE})
    @ResponseBody
    public ResponseEntity<Json> getDocumentation(
            @RequestParam(value = "group", required = false) String swaggerGroup,
            HttpServletRequest servletRequest) {
        return swagger2ControllerWebMvc.getDocumentation(swaggerGroup, servletRequest);
    }
}
