package ru.yandex.autotests.directapi.apiclient;

import java.io.IOException;
import java.util.Arrays;
import java.util.TreeMap;
import java.util.stream.Collectors;

import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ResponseHandler;

import ru.yandex.autotests.directapi.apiclient.version5.MethodInvocationResult;
import ru.yandex.autotests.directapi.exceptions.DirectAPIException;

/**
 * Created by mariabye on 14.10.14.
 */
public class ApiResponseHandler implements ResponseHandler<MethodInvocationResult<String>> {
    private HttpMessage httpMessage;

    public ApiResponseHandler(HttpMessage httpMessage) {
        this.httpMessage = httpMessage;
    }

    @Override
    public MethodInvocationResult<String> handleResponse(HttpResponse response) throws IOException {
        StatusLine statusLine = response.getStatusLine();
        HttpEntity entity = response.getEntity();
        if (statusLine.getStatusCode() == 502) {
            throw new DirectAPIException(statusLine.toString());
        }
        if (entity == null) {
            throw new DirectAPIException("Response contains no content");
        }
        httpMessage.setStatusCode(String.valueOf(statusLine.getStatusCode()));
        String responseData = IOUtils.toString(entity.getContent());
        httpMessage.setResponse(responseData);
        if (responseData.toLowerCase().contains("internal server error")) {
            throw new DirectAPIException("Сервер ответил ошибкой internal server error");
        }
        String responseHeaders = "";
        Header[] units = response.getHeaders(ApiResponseHeaders.UNITS);
        Header[] perlImplementation = response.getHeaders(ApiResponseHeaders.PERL_IMPLEMENTATION);
        Header[] javaImplementation = response.getHeaders(ApiResponseHeaders.JAVA_IMPLEMENTATION);
        Header[] requestId = response.getHeaders(ApiResponseHeaders.REQUEST_ID);
        Header[] getPhrasesLimit = response.getHeaders(ApiResponseHeaders.GET_PHRASES_LIMIT);
        if ((units.length == 1) && (requestId.length == 1)) {
            responseHeaders += '{' + units[0].toString() + ", " + requestId[0].toString() + '}';
        }
        if (getPhrasesLimit.length == 1) {
            responseHeaders += '{' + getPhrasesLimit[0].toString() + '}';
        }
        if (perlImplementation.length == 1) {
            responseHeaders += '{' + perlImplementation[0].toString() + '}';
        }
        if (javaImplementation.length == 1) {
            responseHeaders += '{' + javaImplementation[0].toString() + '}';
        }
        if (!responseHeaders.isEmpty()) {
            httpMessage.setResponseHeaders(responseHeaders);
        }

        httpMessage.setResponseHeaderMap(Arrays.stream(response.getAllHeaders())
                .collect(Collectors.toMap(Header::getName, Header::getValue,
                        (name1, name2) -> name1,
                        () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER))));

        return new MethodInvocationResult<>(responseData, isJavaResponse(perlImplementation));
    }

    private static boolean isJavaResponse(Header[] perlImplementation) {
        try {
            return perlImplementation.length == 0 || !Boolean.valueOf(perlImplementation[0].getValue());
        }
        catch (RuntimeException ex) {
            return false;
        }
    }
}
