package org.chenyang.http.impl.client;

import org.chenyang.commons.logging.Log;
import org.chenyang.commons.logging.LogFactory;
import org.chenyang.http.HttpEntity;
import org.chenyang.http.HttpHost;
import org.chenyang.http.HttpRequest;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.client.ClientProtocolException;
import org.chenyang.http.client.HttpClient;
import org.chenyang.http.client.ResponseHandler;
import org.chenyang.http.client.methods.CloseableHttpResponse;
import org.chenyang.http.client.methods.HttpUriRequest;
import org.chenyang.http.client.utils.URIUtils;
import org.chenyang.http.protocol.HttpContext;
import org.chenyang.http.util.Args;
import org.chenyang.http.util.EntityUtils;
import java.io.Closeable;
import java.io.IOException;
import java.net.URI;

@Contract(
   threading = ThreadingBehavior.SAFE
)
public abstract class CloseableHttpClient implements HttpClient, Closeable {
   private final Log log = LogFactory.getLog(this.getClass());

   protected abstract CloseableHttpResponse doExecute(HttpHost var1, HttpRequest var2, HttpContext var3) throws IOException, ClientProtocolException;

   public CloseableHttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException {
      return this.doExecute(target, request, context);
   }

   public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
      Args.notNull(request, "HTTP request");
      return this.doExecute(determineTarget(request), request, context);
   }

   private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException {
      HttpHost target = null;
      URI requestURI = request.getURI();
      if (requestURI.isAbsolute()) {
         target = URIUtils.extractHost(requestURI);
         if (target == null) {
            throw new ClientProtocolException("URI does not specify a valid host name: " + requestURI);
         }
      }

      return target;
   }

   public CloseableHttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
      return this.execute(request, (HttpContext)null);
   }

   public CloseableHttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
      return this.doExecute(target, request, (HttpContext)null);
   }

   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
      return (T)this.execute((HttpUriRequest)request, (ResponseHandler)responseHandler, (HttpContext)null);
   }

   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
      HttpHost target = determineTarget(request);
      return (T)this.execute(target, request, responseHandler, context);
   }

   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
      return (T)this.execute(target, request, responseHandler, (HttpContext)null);
   }

   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
      Args.notNull(responseHandler, "Response handler");
      CloseableHttpResponse response = this.execute(target, request, context);

      Object var8;
      try {
         T result = responseHandler.handleResponse(response);
         HttpEntity entity = response.getEntity();
         EntityUtils.consume(entity);
         var8 = result;
      } catch (ClientProtocolException t) {
         HttpEntity entity = response.getEntity();

         try {
            EntityUtils.consume(entity);
         } catch (Exception t2) {
            this.log.warn("Error consuming content after an exception.", t2);
         }

         throw t;
      } finally {
         response.close();
      }

      return (T)var8;
   }
}
