/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.dubbo.remoting.http.restclient;

import org.apache.commons.io.IOUtils;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class HttpClientRestClient implements RestClient {
    private final CloseableHttpClient closeableHttpClient;
    private final HttpClientConfig httpClientConfig;

    public HttpClientRestClient(HttpClientConfig clientConfig) {
        closeableHttpClient = createHttpClient();
        httpClientConfig = clientConfig;
    }

    @Override
    public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {

        HttpRequestBase httpRequest = null;
        String httpMethod = requestTemplate.getHttpMethod();

        httpRequest = createHttpUriRequest(httpMethod, requestTemplate);

        if (httpRequest instanceof HttpEntityEnclosingRequest) {
            ((HttpEntityEnclosingRequestBase) httpRequest)
                    .setEntity(new ByteArrayEntity(requestTemplate.getSerializedBody()));
        }

        Map<String, Collection<String>> allHeaders = requestTemplate.getAllHeaders();

        allHeaders.remove("Content-Length");
        // header
        for (String headerName : allHeaders.keySet()) {
            Collection<String> headerValues = allHeaders.get(headerName);

            for (String headerValue : headerValues) {
                httpRequest.addHeader(headerName, headerValue);
            }
        }

        httpRequest.setConfig(getRequestConfig(httpClientConfig));

        CompletableFuture<RestResult> future = new CompletableFuture<>();
        try {
            CloseableHttpResponse response = closeableHttpClient.execute(httpRequest);
            future.complete(new RestResult() {
                @Override
                public String getContentType() {
                    Header header = response.getFirstHeader("Content-Type");
                    return header == null ? null : header.getValue();
                }

                @Override
                public byte[] getBody() throws IOException {
                    if (response.getEntity() == null) {
                        return new byte[0];
                    }
                    return IOUtils.toByteArray(response.getEntity().getContent());
                }

                @Override
                public Map<String, List<String>> headers() {
                    return Arrays.stream(response.getAllHeaders())
                            .collect(Collectors.toMap(Header::getName, h -> Collections.singletonList(h.getValue())));
                }

                @Override
                public byte[] getErrorResponse() throws IOException {
                    return getBody();
                }

                @Override
                public int getResponseCode() {
                    return response.getStatusLine().getStatusCode();
                }

                @Override
                public String getMessage() throws IOException {
                    return appendErrorMessage(
                            response.getStatusLine().getReasonPhrase(), new String(getErrorResponse()));
                }
            });
        } catch (IOException e) {
            future.completeExceptionally(e);
        }
        return future;
    }

    private RequestConfig getRequestConfig(HttpClientConfig clientConfig) {

        // TODO config
        return RequestConfig.custom().build();
    }

    @Override
    public void close() {
        try {
            closeableHttpClient.close();
        } catch (IOException e) {

        }
    }

    @Override
    public void close(int timeout) {}

    @Override
    public boolean isClosed() {
        // TODO close judge
        return true;
    }

    public CloseableHttpClient createHttpClient() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        return HttpClients.custom().setConnectionManager(connectionManager).build();
    }

    protected HttpRequestBase createHttpUriRequest(String httpMethod, RequestTemplate requestTemplate) {
        String uri = requestTemplate.getURL();
        HttpRequestBase httpUriRequest = null;
        if (HttpGet.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpGet(uri);
        } else if (HttpHead.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpHead(uri);
        } else if (HttpPost.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpPost(uri);
        } else if (HttpPut.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpPut(uri);
        } else if (HttpPatch.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpPatch(uri);
        } else if (HttpDelete.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpDelete(uri);
        } else if (HttpOptions.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpOptions(uri);
        } else if (HttpTrace.METHOD_NAME.equals(httpMethod)) {
            httpUriRequest = new HttpTrace(uri);
        } else {
            throw new IllegalArgumentException("Invalid HTTP method: " + httpMethod);
        }
        return httpUriRequest;
    }
}
