package cz.senslog.connector.fetch.azure;

import cz.senslog.connector.model.config.DefaultConfig;
import cz.senslog.connector.fetch.api.ConnectorFetchProvider;
import cz.senslog.connector.fetch.api.ConnectorFetcher;
import cz.senslog.connector.fetch.api.ExecutableFetcher;
import cz.senslog.connector.fetch.azure.auth.AzureAuthConfig;
import cz.senslog.connector.fetch.azure.auth.AuthenticationService;
import cz.senslog.connector.model.azure.AzureModel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import static cz.senslog.connector.fetch.azure.auth.AuthenticationService.newAuthService;
import static cz.senslog.connector.tools.http.HttpClient.newHttpClient;

/**
 * The class {@code ConnectorFetchAzureProvider} represents a concrete implementation of {@link ConnectorFetchProvider}.
 * Contains basic functionality to configure implementation of {@link ConnectorFetcher} from the default configuration.
 *
 * @author Lukas Cerny
 * @version 1.0
 * @since 1.0
 */
public final class ConnectorFetchAzureProvider implements ConnectorFetchProvider {

    private static final Logger logger = LogManager.getLogger(ConnectorFetchAzureProvider.class);

    @Override
    public ExecutableFetcher<AzureModel> createExecutableFetcher(DefaultConfig defaultConfig) {
        logger.info("Initialization a new fetch provider {}.", ConnectorFetchAzureProvider.class);

        logger.debug("Creating a new configuration.");
        AzureConfig config = new AzureConfig(defaultConfig);
        logger.info("Configuration for {} was created successfully.", ConnectorFetcher.class);

        logger.debug("Getting a configuration for authentication.");
        AzureAuthConfig authConfig = config.getAuthentication();

        logger.info("Initialization a new Azure authentication service.");
        AuthenticationService authService = newAuthService(authConfig, newHttpClient());

        logger.debug("Creating a new instance of {}.", AzureFetcher.class);
        AzureFetcher fetcher = new AzureFetcher(config, authService, newHttpClient());
        logger.info("Fetcher for {} was created successfully.", AzureFetcher.class);

        logger.debug("Getting a configuration for proxy session.");
        AzureSessionProxyConfig proxyConfig = config.getSessionProxy();

        ExecutableFetcher<AzureModel> executor;
        if (proxyConfig != null) {
            logger.debug("Creating a new instance of {}.", AzureProxySession.class);
            AzureProxySession proxySession = new AzureProxySession(fetcher, proxyConfig, newHttpClient());
            logger.info("Fetcher session for {} was created successfully.", AzureProxySession.class);
            executor = ExecutableFetcher.createWithProxySession(proxySession);
        } else {
            executor = ExecutableFetcher.create(fetcher);
        }
        logger.info("Fetcher executor for {} was created successfully.", AzureFetcher.class);

        return executor;
    }
}
