package cn.reghao.tnb.gateway.admin.handler;

import cn.reghao.jutil.jdk.web.result.WebResult;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author reghao
 * @date 2022-09-01 17:32:25
 */
@Service
public class ServiceRouteHandler {
    private final DiscoveryClient discoveryClient;

    public ServiceRouteHandler(DiscoveryClient discoveryClient) {
        this.discoveryClient = discoveryClient;
    }

    public Mono<ServerResponse> getConfig(ServerRequest request) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just("register "), String.class);
    }

    /**
     * 注册服务
     *
     * @param
     * @return
     * @date 2019-11-19 上午10:58
     */
    public Mono<ServerResponse> registerService(ServerRequest request) {
        String service = request.pathVariable("service");

        List<PredicateDefinition> predDefs = new ArrayList<>();
        PredicateDefinition predDef = new PredicateDefinition();
        predDef.setName("Path");
        predDef.addArg("pattern", "/api/");
        predDefs.add(predDef);

        List<FilterDefinition> filterDefs = new ArrayList<>();
        FilterDefinition filterDef = new FilterDefinition();
        filterDef.setName("StripPrefix");
        filterDef.addArg("parts", "1");
        filterDefs.add(filterDef);

        URI uri = null;
        try {
            uri = new URI("lb://127.0.0.1");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        RouteDefinition routeDef = new RouteDefinition();
        routeDef.setId("");
        routeDef.setPredicates(predDefs);
        routeDef.setFilters(filterDefs);
        routeDef.setUri(uri);
        routeDef.setOrder(0);

        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
                .body(Mono.just("register " + service), String.class);
    }

    /**
     * 注销服务
     *
     * @param
     * @return
     * @date 2019-11-19 上午11:00
     */
    public Mono<ServerResponse> deregisterService(ServerRequest request) {
        String service = request.pathVariable("service");

        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
                .body(Mono.just("deregister " + service), String.class);
    }

    public Mono<ServerResponse> getAllServices(ServerRequest request) {
        StringBuilder sb = new StringBuilder();
        List<String> services = discoveryClient.getServices();
        services.forEach(srv -> {
            List<ServiceInstance> list = discoveryClient.getInstances(srv);
            list.forEach(instance -> {
                String serviceId = instance.getServiceId();
                String instanceId = instance.getInstanceId();
                String host = instance.getHost();
                int port = instance.getPort();
                sb.append(String.format("%s-%s: %s:%s", serviceId, instanceId, host, port)).append(System.lineSeparator());
            });
        });

        // Flux<List<String>> -> Flux<String>
        Flux<String> flux = Flux.just(services).flatMap(Flux::fromIterable);
        Flux<String> flux1 = Flux.just(WebResult.success(services));
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(flux1, String.class);
    }
}
