package com.cameleer.server.app.http.config;

import com.cameleer.server.app.http.ApacheOutboundHttpClientFactory;
import com.cameleer.server.app.http.SslContextBuilder;
import com.cameleer.server.core.http.OutboundHttpClientFactory;
import com.cameleer.server.core.http.OutboundHttpProperties;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;

@Configuration
@ConfigurationProperties(prefix = "cameleer.server.outbound-http")
public class OutboundHttpConfig {

    private static final Logger log = LoggerFactory.getLogger(OutboundHttpConfig.class);

    private boolean trustAll = false;
    private List<String> trustedCaPemPaths = List.of();
    private long defaultConnectTimeoutMs = 2000;
    private long defaultReadTimeoutMs = 5000;
    private String proxyUrl;
    private String proxyUsername;
    private String proxyPassword;

    public void setTrustAll(boolean trustAll) { this.trustAll = trustAll; }
    public void setTrustedCaPemPaths(List<String> paths) { this.trustedCaPemPaths = paths == null ? List.of() : List.copyOf(paths); }
    public void setDefaultConnectTimeoutMs(long v) { this.defaultConnectTimeoutMs = v; }
    public void setDefaultReadTimeoutMs(long v) { this.defaultReadTimeoutMs = v; }
    public void setProxyUrl(String v) { this.proxyUrl = v; }
    public void setProxyUsername(String v) { this.proxyUsername = v; }
    public void setProxyPassword(String v) { this.proxyPassword = v; }

    @PostConstruct
    void validate() {
        if (trustAll) {
            log.warn("cameleer.server.outbound-http.trust-all is ON - all outbound HTTPS cert validation is DISABLED. Do not use in production.");
        }
        for (String p : trustedCaPemPaths) {
            if (!Files.exists(Path.of(p))) {
                throw new IllegalStateException("Configured trusted CA PEM path does not exist: " + p);
            }
            log.info("Outbound HTTP: trusting additional CA from {}", p);
        }
    }

    @Bean
    public OutboundHttpProperties outboundHttpProperties() {
        return new OutboundHttpProperties(
                trustAll,
                trustedCaPemPaths,
                Duration.ofMillis(defaultConnectTimeoutMs),
                Duration.ofMillis(defaultReadTimeoutMs),
                proxyUrl,
                proxyUsername,
                proxyPassword
        );
    }

    @Bean
    public SslContextBuilder sslContextBuilder() {
        return new SslContextBuilder();
    }

    @Bean
    public OutboundHttpClientFactory outboundHttpClientFactory(OutboundHttpProperties props, SslContextBuilder builder) {
        return new ApacheOutboundHttpClientFactory(props, builder);
    }
}
