package org.chenyang.http.client.protocol;

import org.chenyang.http.Header;
import org.chenyang.http.HttpException;
import org.chenyang.http.HttpHost;
import org.chenyang.http.HttpRequest;
import org.chenyang.http.HttpRequestInterceptor;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.client.CookieStore;
import org.chenyang.http.client.config.RequestConfig;
import org.chenyang.http.client.methods.HttpUriRequest;
import org.chenyang.http.config.Lookup;
import org.chenyang.http.conn.routing.RouteInfo;
import org.chenyang.http.cookie.Cookie;
import org.chenyang.http.cookie.CookieOrigin;
import org.chenyang.http.cookie.CookieSpec;
import org.chenyang.http.cookie.CookieSpecProvider;
import org.chenyang.http.protocol.HttpContext;
import org.chenyang.http.util.Args;
import org.chenyang.http.util.TextUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Contract(
   threading = ThreadingBehavior.IMMUTABLE
)
public class RequestAddCookies implements HttpRequestInterceptor {
   public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
      Args.notNull(request, "HTTP request");
      Args.notNull(context, "HTTP context");
      String method = request.getRequestLine().getMethod();
      if (!method.equalsIgnoreCase("CONNECT")) {
         HttpClientContext clientContext = HttpClientContext.adapt(context);
         CookieStore cookieStore = clientContext.getCookieStore();
         if (cookieStore != null) {
            Lookup<CookieSpecProvider> registry = clientContext.getCookieSpecRegistry();
            if (registry != null) {
               HttpHost targetHost = clientContext.getTargetHost();
               if (targetHost != null) {
                  RouteInfo route = clientContext.getHttpRoute();
                  if (route != null) {
                     RequestConfig config = clientContext.getRequestConfig();
                     String policy = config.getCookieSpec();
                     if (policy == null) {
                        policy = "default";
                     }

                     URI requestURI = null;
                     if (request instanceof HttpUriRequest) {
                        requestURI = ((HttpUriRequest)request).getURI();
                     } else {
                        try {
                           requestURI = new URI(request.getRequestLine().getUri());
                        } catch (URISyntaxException var25) {
                        }
                     }

                     String path = requestURI != null ? requestURI.getPath() : null;
                     String hostName = targetHost.getHostName();
                     int port = targetHost.getPort();
                     if (port < 0) {
                        port = route.getTargetHost().getPort();
                     }

                     CookieOrigin cookieOrigin = new CookieOrigin(hostName, port >= 0 ? port : 0, !TextUtils.isEmpty(path) ? path : "/", route.isSecure());
                     CookieSpecProvider provider = registry.lookup(policy);
                     if (provider != null) {
                        CookieSpec cookieSpec = provider.create(clientContext);
                        List<Cookie> cookies = cookieStore.getCookies();
                        List<Cookie> matchedCookies = new ArrayList();
                        Date now = new Date();
                        boolean expired = false;

                        for(Cookie cookie : cookies) {
                           if (!cookie.isExpired(now)) {
                              if (cookieSpec.match(cookie, cookieOrigin)) {
                                 matchedCookies.add(cookie);
                              }
                           } else {
                              expired = true;
                           }
                        }

                        if (expired) {
                           cookieStore.clearExpired(now);
                        }

                        if (!matchedCookies.isEmpty()) {
                           for(Header header : cookieSpec.formatCookies(matchedCookies)) {
                              request.addHeader(header);
                           }
                        }

                        int ver = cookieSpec.getVersion();
                        if (ver > 0) {
                           Header header = cookieSpec.getVersionHeader();
                           if (header != null) {
                              request.addHeader(header);
                           }
                        }

                        context.setAttribute("http.cookie-spec", cookieSpec);
                        context.setAttribute("http.cookie-origin", cookieOrigin);
                     }
                  }
               }
            }
         }
      }
   }
}
