package org.chenyang.http.impl.client;

import org.chenyang.commons.logging.Log;
import org.chenyang.commons.logging.LogFactory;
import org.chenyang.http.Header;
import org.chenyang.http.HttpHost;
import org.chenyang.http.HttpResponse;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.auth.AuthOption;
import org.chenyang.http.auth.AuthScheme;
import org.chenyang.http.auth.AuthScope;
import org.chenyang.http.auth.AuthenticationException;
import org.chenyang.http.auth.Credentials;
import org.chenyang.http.auth.MalformedChallengeException;
import org.chenyang.http.client.AuthCache;
import org.chenyang.http.client.AuthenticationHandler;
import org.chenyang.http.client.AuthenticationStrategy;
import org.chenyang.http.client.CredentialsProvider;
import org.chenyang.http.protocol.HttpContext;
import org.chenyang.http.util.Args;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;

/** @deprecated */
@Deprecated
@Contract(
   threading = ThreadingBehavior.IMMUTABLE
)
class AuthenticationStrategyAdaptor implements AuthenticationStrategy {
   private final Log log = LogFactory.getLog(this.getClass());
   private final AuthenticationHandler handler;

   public AuthenticationStrategyAdaptor(AuthenticationHandler handler) {
      this.handler = handler;
   }

   public boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) {
      return this.handler.isAuthenticationRequested(response, context);
   }

   public Map<String, Header> getChallenges(HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException {
      return this.handler.getChallenges(response, context);
   }

   public Queue<AuthOption> select(Map<String, Header> challenges, HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException {
      Args.notNull(challenges, "Map of auth challenges");
      Args.notNull(authhost, "Host");
      Args.notNull(response, "HTTP response");
      Args.notNull(context, "HTTP context");
      Queue<AuthOption> options = new LinkedList();
      CredentialsProvider credsProvider = (CredentialsProvider)context.getAttribute("http.auth.credentials-provider");
      if (credsProvider == null) {
         this.log.debug("Credentials provider not set in the context");
         return options;
      } else {
         AuthScheme authScheme;
         try {
            authScheme = this.handler.selectScheme(challenges, response, context);
         } catch (AuthenticationException ex) {
            if (this.log.isWarnEnabled()) {
               this.log.warn(ex.getMessage(), ex);
            }

            return options;
         }

         String id = authScheme.getSchemeName();
         Header challenge = (Header)challenges.get(id.toLowerCase(Locale.ROOT));
         authScheme.processChallenge(challenge);
         AuthScope authScope = new AuthScope(authhost.getHostName(), authhost.getPort(), authScheme.getRealm(), authScheme.getSchemeName());
         Credentials credentials = credsProvider.getCredentials(authScope);
         if (credentials != null) {
            options.add(new AuthOption(authScheme, credentials));
         }

         return options;
      }
   }

   public void authSucceeded(HttpHost authhost, AuthScheme authScheme, HttpContext context) {
      AuthCache authCache = (AuthCache)context.getAttribute("http.auth.auth-cache");
      if (this.isCachable(authScheme)) {
         if (authCache == null) {
            authCache = new BasicAuthCache();
            context.setAttribute("http.auth.auth-cache", authCache);
         }

         if (this.log.isDebugEnabled()) {
            this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + authhost);
         }

         authCache.put(authhost, authScheme);
      }

   }

   public void authFailed(HttpHost authhost, AuthScheme authScheme, HttpContext context) {
      AuthCache authCache = (AuthCache)context.getAttribute("http.auth.auth-cache");
      if (authCache != null) {
         if (this.log.isDebugEnabled()) {
            this.log.debug("Removing from cache '" + authScheme.getSchemeName() + "' auth scheme for " + authhost);
         }

         authCache.remove(authhost);
      }
   }

   private boolean isCachable(AuthScheme authScheme) {
      if (authScheme != null && authScheme.isComplete()) {
         String schemeName = authScheme.getSchemeName();
         return schemeName.equalsIgnoreCase("Basic");
      } else {
         return false;
      }
   }

   public AuthenticationHandler getHandler() {
      return this.handler;
   }
}
