package com.inspect.gateway.config;

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

import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import javax.annotation.Resource;

@Component
public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer {
    public static final String SWAGGER2URL = "/v2/api-docs";
    public static final String SWAGGER_UI = "/swagger-ui/**";
    public static final String SWAGGER_UI_CLASSPATH = "classpath:/META-INF/resources/webjars/springfox-swagger-ui/";

    @Resource
    private RouteLocator routeLocator;

    private final GatewayProperties gatewayProperties;

    public SwaggerProvider(GatewayProperties gatewayProperties) {
        this.gatewayProperties = gatewayProperties;
    }

    public List<SwaggerResource> get() {
        List<SwaggerResource> resourceList = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        this.routeLocator.getRoutes().subscribe((route) -> {
            routes.add(route.getId());
        });
        this.gatewayProperties.getRoutes().stream().filter((routeDefinition) -> routes.contains(routeDefinition.getId())).forEach((routeDefinition) -> {
            routeDefinition.getPredicates().stream().filter((predicateDefinition) -> "Path".equalsIgnoreCase(predicateDefinition.getName())).filter((predicateDefinition) -> !"inspect-admin".equalsIgnoreCase(routeDefinition.getId())).forEach((predicateDefinition) -> {
                resourceList.add(this.swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs().get("_genkey_0").replace("/**", SWAGGER2URL)));
            });
        });
        return resourceList;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }

    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(SWAGGER_UI).addResourceLocations(SWAGGER_UI_CLASSPATH);
    }
}
