package ru.yandex.webmaster3.core.nanny;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.util.UriComponentsBuilder;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.HttpConstants;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;

import java.io.IOException;

/**
 * @author avhaliullin
 */
public class NannyService {
    private static final Logger log = LoggerFactory.getLogger(NannyService.class);

    private CloseableHttpClient httpClient;
    private static final int socketTimeoutMs = 5_000;

    private String nannyApiBaseUrl;
    private String authorizationToken;

    public void init() {
        SocketConfig socketConfig = SocketConfig.custom()
                .setSoTimeout(socketTimeoutMs)
                .build();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(HttpConstants.DEFAULT_CONNECT_TIMEOUT)
                .setSocketTimeout(socketTimeoutMs)
                .setConnectionRequestTimeout(HttpConstants.DEFAULT_CONNECTION_REQUEST_TIMEOUT)
                .build();

        httpClient = HttpClientBuilder.create()
                .setDefaultSocketConfig(socketConfig)
                .setMaxConnPerRoute(16)
                .setMaxConnTotal(16)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    public <T> T queryNanny(NannyQuery<T> query) {
        HttpUriRequest request = query.makeRequest(UriComponentsBuilder.fromUriString(nannyApiBaseUrl));
        request.setHeader("Authorization", "OAuth " + authorizationToken);
        log.info("Querying nanny: {}", request);
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            return query.parseResult(response);
        } catch (IOException e) {
            throw new WebmasterException("Nanny request " + request + " failed",
                    new WebmasterErrorResponse.NannyErrorResponse(getClass(), e), e);
        }
    }

    @Required
    public void setNannyApiBaseUrl(String nannyApiBaseUrl) {
        this.nannyApiBaseUrl = nannyApiBaseUrl;
    }

    @Required
    public void setAuthorizationToken(String authorizationToken) {
        this.authorizationToken = authorizationToken;
    }
}
