package ink.wgink.common.config;

import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.properties.swagger.SwaggerProperties;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseBuilder;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName: SwaggerConfig
 * @Description: swagger的配置文件
 * @Author: WangGeng
 * @Date: 2019/3/1 3:58 PM
 * @Version: 1.0
 **/
@Configuration
public class SwaggerConfig {
    @Autowired
    private SwaggerProperties swaggerProperties;

    @Bean
    public Docket createRestApiSystem() {
        return new Docket(DocumentationType.OAS_30)
                .enable(swaggerProperties.getActive())
                .globalResponses(HttpMethod.GET, globalResponses())
                .globalResponses(HttpMethod.POST, globalResponses())
                .globalResponses(HttpMethod.PUT, globalResponses())
                .globalResponses(HttpMethod.DELETE, globalResponses())
                .globalResponses(HttpMethod.HEAD, globalResponses())
                .globalResponses(HttpMethod.OPTIONS, globalResponses())
                .pathMapping("/")
                .groupName(ISystemConstant.API_GROUP_SYSTEM)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/*" + ISystemConstant.API_PREFIX + "/**"))
                .build();
    }

    @Bean
    public Docket createRestApiResource() {
        return new Docket(DocumentationType.OAS_30)
                .enable(swaggerProperties.getActive())
                .globalResponses(HttpMethod.GET, globalResponses())
                .globalResponses(HttpMethod.POST, globalResponses())
                .globalResponses(HttpMethod.PUT, globalResponses())
                .globalResponses(HttpMethod.DELETE, globalResponses())
                .globalResponses(HttpMethod.HEAD, globalResponses())
                .globalResponses(HttpMethod.OPTIONS, globalResponses())
                .pathMapping("/")
                .groupName(ISystemConstant.API_GROUP_RESOURCE)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/*" + ISystemConstant.RESOURCE_PREFIX + "/**"))
                .build();
    }

    @Bean
    public Docket createRestApiApp() {
        return new Docket(DocumentationType.OAS_30)
                .enable(swaggerProperties.getActive())
                .globalResponses(HttpMethod.GET, globalResponses())
                .globalResponses(HttpMethod.POST, globalResponses())
                .globalResponses(HttpMethod.PUT, globalResponses())
                .globalResponses(HttpMethod.DELETE, globalResponses())
                .globalResponses(HttpMethod.HEAD, globalResponses())
                .globalResponses(HttpMethod.OPTIONS, globalResponses())
                .pathMapping("/")
                .groupName(ISystemConstant.API_GROUP_APP)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/*" + ISystemConstant.APP_PREFIX + "/**"))
                .build();
    }

    @Bean
    public Docket createRestApiWechat() {
        return new Docket(DocumentationType.OAS_30)
                .enable(swaggerProperties.getActive())
                .globalResponses(HttpMethod.GET, globalResponses())
                .globalResponses(HttpMethod.POST, globalResponses())
                .globalResponses(HttpMethod.PUT, globalResponses())
                .globalResponses(HttpMethod.DELETE, globalResponses())
                .globalResponses(HttpMethod.HEAD, globalResponses())
                .globalResponses(HttpMethod.OPTIONS, globalResponses())
                .pathMapping("/")
                .groupName(ISystemConstant.API_GROUP_WECHAT)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/*" + ISystemConstant.WECHAT_PREFIX + "/**"))
                .build();
    }

    @Bean
    public Docket createRestApiWechatMiniapp() {
        return new Docket(DocumentationType.OAS_30)
                .enable(swaggerProperties.getActive())
                .globalResponses(HttpMethod.GET, globalResponses())
                .globalResponses(HttpMethod.POST, globalResponses())
                .globalResponses(HttpMethod.PUT, globalResponses())
                .globalResponses(HttpMethod.DELETE, globalResponses())
                .globalResponses(HttpMethod.HEAD, globalResponses())
                .globalResponses(HttpMethod.OPTIONS, globalResponses())
                .pathMapping("/")
                .groupName(ISystemConstant.API_GROUP_WECHAT_MINI_APP)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.ant("/*" + ISystemConstant.WECHAT_MINI_APP_PREFIX + "/**"))
                .build();
    }

    /**
     * 全局响应
     *
     * @return
     */
    private List<Response> globalResponses() {
        List<Response> responses = new ArrayList<>();
        responses.add(new ResponseBuilder().code("200").description("成功").build());
        responses.add(new ResponseBuilder().code("400").description("请求失败").build());
        responses.add(new ResponseBuilder().code("401").description("认证失败").build());
        responses.add(new ResponseBuilder().code("403").description("禁止访问").build());
        responses.add(new ResponseBuilder().code("404").description("未找到").build());
        responses.add(new ResponseBuilder().code("500").description("系统错误").build());
        return responses;
    }


    /**
     * 设置授权信息
     */
    private List<SecurityScheme> securitySchemes() {
        ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", In.HEADER.toValue());
        return Collections.singletonList(apiKey);
    }

    /**
     * 授权信息全局应用
     */
    private List<SecurityContext> securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                        .build()
        );
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .contact(new Contact("WenG", null, "450292408@qq.com"))
                .version(swaggerProperties.getVersion())
                .build();
    }

}
