package ru.yandex.qe.hitman.tvm.v2;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.time.Instant;
import java.util.Collections;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.qe.hitman.tvm.TvmConstants;

/**
 * Created by akhvorov on 31.07.17.
 */
public class TVM2TicketServiceImpl extends AbstractTVM2TicketService {

    private static final Logger LOG = LoggerFactory.getLogger(TVM2TicketServiceImpl.class);

    private static final HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
            .setDefaultRequestConfig(
                    RequestConfig.custom()
                            .setConnectTimeout(1_000)
                            .setSocketTimeout(60_0000)
                            .build()
            );

    public TVM2TicketServiceImpl(final ObjectMapper objectMapper) {
        super(objectMapper);
    }

    public <T extends HttpRequest> T addTicketHeader(final T request, final String clientId,
                                                     final String destinationId, final String secret) {
        return addTicketHeader(request, TvmConstants.TVM_SERVICE_HEADER_NAME, clientId, destinationId, secret);
    }

    public <T extends HttpRequest> T addTicketHeader(final T request, final String headerName, final String clientId,
                                                     final String destinationId, final String secret) {
        final String timestamp = Long.toString(Instant.now().toEpochMilli() / 1000);
        final String sign = sign(destinationId, secret, timestamp);
        request.addHeader(headerName, ticket(clientId, destinationId, sign, timestamp));
        return request;
    }

    private String ticket(final String clientId, final String destinationId, final String sign,
                          final String timestamp) {
        try {
            final HttpUriRequest request =
                    buildRequest(clientId, Collections.singletonList(destinationId), sign, timestamp);
            final long startMs = System.currentTimeMillis();
            final HttpResponse response = httpClientBuilder.build().execute(request);
            LOG.info("Get ticket from TVM in {}ms", System.currentTimeMillis() - startMs);
            return parseResponse(response, destinationId);
        } catch (IOException e) {
            throw new UncheckedIOException("can't execute request", e);
        }
    }
}
