package com.lanyuanxiaoyao.service.cloud;

import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.service.cloud.entity.PrometheusTarget;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Maps;
import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.api.map.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 服务查询
 *
 * @author lanyuanxiaoyao
 * @date 2023-12-14
 */
@RestController
@RequestMapping("cloud")
public class CloudController {
    private static final Logger logger = LoggerFactory.getLogger(CloudQueryApplication.class);

    private final DiscoveryClient client;

    public CloudController(DiscoveryClient client) {
        this.client = client;
    }

    @GetMapping("services")
    public ImmutableList<String> infoQueryServices(
            @RequestParam("service_name") String serviceName,
            @RequestParam(value = "with_schema", defaultValue = "true") Boolean withSchema,
            @RequestParam(value = "with_port", defaultValue = "true") Boolean withPort
    ) {
        return Lists.immutable.ofAll(client.getServices())
                .select(name -> StrUtil.equals(name, serviceName))
                .flatCollect(name ->
                        Lists.immutable.ofAll(client.getInstances(name))
                                .collect(instance -> {
                                    if (withSchema)
                                        if (withPort) return instance.getUri().toString();
                                        else return StrUtil.format("{}://{}", instance.getScheme(), instance.getHost());
                                    else if (withPort)
                                        return StrUtil.format("{}:{}", instance.getHost(), instance.getPort());
                                    else return instance.getHost();
                                }))
                .toSortedList()
                .toImmutable();
    }

    @GetMapping("targets")
    public ImmutableList<PrometheusTarget> prometheusTargets() {
        return Lists.immutable.ofAll(client.getServices())
                .collect(name -> {
                    ImmutableList<String> targets = Lists.immutable.ofAll(client.getInstances(name))
                            .collect(instance -> instance.getUri().toString());
                    ImmutableMap<String, String> labels = Maps.immutable.of("application", name);
                    return new PrometheusTarget(targets, labels);
                });
    }
}
