package org.chenyang.http.impl.client;

import org.chenyang.commons.logging.Log;
import org.chenyang.commons.logging.LogFactory;
import org.chenyang.http.HttpHost;
import org.chenyang.http.HttpRequest;
import org.chenyang.http.HttpResponse;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.client.HttpClient;
import org.chenyang.http.client.ResponseHandler;
import org.chenyang.http.client.ServiceUnavailableRetryStrategy;
import org.chenyang.http.client.methods.HttpUriRequest;
import org.chenyang.http.conn.ClientConnectionManager;
import org.chenyang.http.params.HttpParams;
import org.chenyang.http.protocol.HttpContext;
import org.chenyang.http.util.Args;
import org.chenyang.http.util.EntityUtils;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URI;

/** @deprecated */
@Deprecated
@Contract(
   threading = ThreadingBehavior.SAFE_CONDITIONAL
)
public class AutoRetryHttpClient implements HttpClient {
   private final HttpClient backend;
   private final ServiceUnavailableRetryStrategy retryStrategy;
   private final Log log;

   public AutoRetryHttpClient(HttpClient client, ServiceUnavailableRetryStrategy retryStrategy) {
      this.log = LogFactory.getLog(this.getClass());
      Args.notNull(client, "HttpClient");
      Args.notNull(retryStrategy, "ServiceUnavailableRetryStrategy");
      this.backend = client;
      this.retryStrategy = retryStrategy;
   }

   public AutoRetryHttpClient() {
      this(new DefaultHttpClient(), new DefaultServiceUnavailableRetryStrategy());
   }

   public AutoRetryHttpClient(ServiceUnavailableRetryStrategy config) {
      this(new DefaultHttpClient(), config);
   }

   public AutoRetryHttpClient(HttpClient client) {
      this(client, new DefaultServiceUnavailableRetryStrategy());
   }

   public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException {
      HttpContext defaultContext = null;
      return this.execute(target, request, defaultContext);
   }

   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException {
      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 {
      HttpResponse resp = this.execute(target, request, context);
      return responseHandler.handleResponse(resp);
   }

   public HttpResponse execute(HttpUriRequest request) throws IOException {
      HttpContext context = null;
      return this.execute(request, context);
   }

   public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException {
      URI uri = request.getURI();
      HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
      return this.execute((HttpHost)httpHost, request, context);
   }

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

   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException {
      HttpResponse resp = this.execute(request, context);
      return responseHandler.handleResponse(resp);
   }

   public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException {
      int c = 1;

      while(true) {
         HttpResponse response = this.backend.execute(target, request, context);

         try {
            if (!this.retryStrategy.retryRequest(response, c, context)) {
               return response;
            }

            EntityUtils.consume(response.getEntity());
            long nextInterval = this.retryStrategy.getRetryInterval();

            try {
               this.log.trace("Wait for " + nextInterval);
               Thread.sleep(nextInterval);
            } catch (InterruptedException var10) {
               Thread.currentThread().interrupt();
               throw new InterruptedIOException();
            }
         } catch (RuntimeException ex) {
            try {
               EntityUtils.consume(response.getEntity());
            } catch (IOException ioex) {
               this.log.warn("I/O error consuming response content", ioex);
            }

            throw ex;
         }

         ++c;
      }
   }

   public ClientConnectionManager getConnectionManager() {
      return this.backend.getConnectionManager();
   }

   public HttpParams getParams() {
      return this.backend.getParams();
   }
}
