package org.chenyang.http.protocol;

import org.chenyang.http.HttpConnection;
import org.chenyang.http.HttpException;
import org.chenyang.http.HttpHost;
import org.chenyang.http.HttpInetConnection;
import org.chenyang.http.HttpRequest;
import org.chenyang.http.HttpRequestInterceptor;
import org.chenyang.http.HttpVersion;
import org.chenyang.http.ProtocolException;
import org.chenyang.http.ProtocolVersion;
import org.chenyang.http.annotation.Contract;
import org.chenyang.http.annotation.ThreadingBehavior;
import org.chenyang.http.util.Args;
import java.io.IOException;
import java.net.InetAddress;

@Contract(
   threading = ThreadingBehavior.IMMUTABLE
)
public class RequestTargetHost implements HttpRequestInterceptor {
   public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
      Args.notNull(request, "HTTP request");
      HttpCoreContext coreContext = HttpCoreContext.adapt(context);
      ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
      String method = request.getRequestLine().getMethod();
      if (!method.equalsIgnoreCase("CONNECT") || !ver.lessEquals(HttpVersion.HTTP_1_0)) {
         if (!request.containsHeader("Host")) {
            HttpHost targetHost = coreContext.getTargetHost();
            if (targetHost == null) {
               HttpConnection conn = coreContext.getConnection();
               if (conn instanceof HttpInetConnection) {
                  InetAddress address = ((HttpInetConnection)conn).getRemoteAddress();
                  int port = ((HttpInetConnection)conn).getRemotePort();
                  if (address != null) {
                     targetHost = new HttpHost(address.getHostName(), port);
                  }
               }

               if (targetHost == null) {
                  if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
                     return;
                  }

                  throw new ProtocolException("Target host missing");
               }
            }

            request.addHeader("Host", targetHost.toHostString());
         }

      }
   }
}
