package de.gecheckt.pdf.umbenenner.bootstrap;

import java.util.Objects;

import de.gecheckt.pdf.umbenenner.adapter.out.ai.AnthropicClaudeHttpAdapter;
import de.gecheckt.pdf.umbenenner.adapter.out.ai.OpenAiHttpAdapter;
import de.gecheckt.pdf.umbenenner.adapter.out.bootstrap.validation.InvalidStartConfigurationException;
import de.gecheckt.pdf.umbenenner.application.config.provider.AiProviderFamily;
import de.gecheckt.pdf.umbenenner.application.config.provider.ProviderConfiguration;
import de.gecheckt.pdf.umbenenner.application.port.out.AiInvocationPort;

/**
 * Selects and instantiates the active {@link AiInvocationPort} implementation
 * based on the configured provider family.
 * <p>
 * This component lives in the bootstrap layer and is the single point where
 * the active provider family is mapped to its corresponding adapter implementation.
 * Exactly one provider is selected per application run; the selection is driven
 * by the value of {@code ai.provider.active}.
 *
 * <h2>Registered providers</h2>
 * <ul>
 *   <li>{@link AiProviderFamily#OPENAI_COMPATIBLE} — {@link OpenAiHttpAdapter}</li>
 *   <li>{@link AiProviderFamily#CLAUDE} — {@link AnthropicClaudeHttpAdapter}</li>
 * </ul>
 *
 * <h2>Hard start failure</h2>
 * <p>
 * If the requested provider family has no registered implementation, an
 * {@link InvalidStartConfigurationException} is thrown immediately, which the
 * bootstrap runner maps to exit code 1.
 */
public class AiProviderSelector {

    /**
     * Selects and constructs the {@link AiInvocationPort} implementation for the given
     * provider family using the supplied provider configuration.
     *
     * @param family the active provider family; must not be {@code null}
     * @param config the configuration for the active provider; must not be {@code null}
     * @return the constructed adapter instance; never {@code null}
     * @throws InvalidStartConfigurationException if no implementation is registered
     *         for the requested provider family
     */
    public AiInvocationPort select(AiProviderFamily family, ProviderConfiguration config) {
        Objects.requireNonNull(family, "provider family must not be null");
        Objects.requireNonNull(config, "provider configuration must not be null");

        if (family == AiProviderFamily.OPENAI_COMPATIBLE) {
            return new OpenAiHttpAdapter(config);
        }

        if (family == AiProviderFamily.CLAUDE) {
            return new AnthropicClaudeHttpAdapter(config);
        }

        throw new InvalidStartConfigurationException(
                "No AI adapter implementation registered for provider family: "
                + family.getIdentifier()
                + ". Supported in the current build: openai-compatible, claude");
    }
}
