package com.lanyuanxiaoyao.service.command.configuration;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.dtflys.forest.auth.BasicAuth;
import com.dtflys.forest.http.ForestAddress;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.interceptor.Interceptor;
import com.lanyuanxiaoyao.service.common.Constants;
import java.net.URI;
import java.net.URL;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;

/**
 * @author lanyuanxiaoyao
 * @date 2023-04-24
 */
@Component
public class SpringCloudDiscoveryInterceptor implements Interceptor<Object> {
    private static final Logger logger = LoggerFactory.getLogger(SpringCloudDiscoveryInterceptor.class);

    private final DiscoveryClient discoveryClient;

    public SpringCloudDiscoveryInterceptor(DiscoveryClient discoveryClient) {
        logger.info("Services: {}", discoveryClient.getServices());
        this.discoveryClient = discoveryClient;
    }

    @Override
    public boolean beforeExecute(ForestRequest request) {
        // Load
        URL url = URLUtil.url(request.getUrl());
        String host = url.getHost();
        if (StrUtil.isNotBlank(host)) {
            ImmutableList<String> urls = Lists.immutable.ofAll(discoveryClient.getInstances(host))
                    .collect(instance -> instance.getUri().toString());
            if (ObjectUtil.isNotEmpty(urls)) {
                @SuppressWarnings("DataFlowIssue")
                String targetUrl = urls.get(RandomUtil.randomInt(urls.size()));
                URI uri = URI.create(targetUrl);
                request.setAddress(new ForestAddress(uri.getScheme(), uri.getHost(), uri.getPort()));
            }
        }

        // Basic auth
        BasicAuth basicAuth = new BasicAuth(Constants.SPRING_SECURITY_USERNAME, Constants.SPRING_SECURITY_PASSWORD_PLAIN);
        basicAuth.enhanceAuthorization(request);

        return Interceptor.super.beforeExecute(request);
    }
}
