package org.chenyang.http.protocol;

import org.chenyang.http.HttpEntity;
import org.chenyang.http.HttpException;
import org.chenyang.http.HttpResponse;
import org.chenyang.http.HttpResponseInterceptor;
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;

@Contract(
   threading = ThreadingBehavior.IMMUTABLE
)
public class ResponseContent implements HttpResponseInterceptor {
   private final boolean overwrite;

   public ResponseContent() {
      this(false);
   }

   public ResponseContent(boolean overwrite) {
      this.overwrite = overwrite;
   }

   public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
      Args.notNull(response, "HTTP response");
      if (this.overwrite) {
         response.removeHeaders("Transfer-Encoding");
         response.removeHeaders("Content-Length");
      } else {
         if (response.containsHeader("Transfer-Encoding")) {
            throw new ProtocolException("Transfer-encoding header already present");
         }

         if (response.containsHeader("Content-Length")) {
            throw new ProtocolException("Content-Length header already present");
         }
      }

      ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
      HttpEntity entity = response.getEntity();
      if (entity != null) {
         long len = entity.getContentLength();
         if (entity.isChunked() && !ver.lessEquals(HttpVersion.HTTP_1_0)) {
            response.addHeader("Transfer-Encoding", "chunked");
         } else if (len >= 0L) {
            response.addHeader("Content-Length", Long.toString(entity.getContentLength()));
         }

         if (entity.getContentType() != null && !response.containsHeader("Content-Type")) {
            response.addHeader(entity.getContentType());
         }

         if (entity.getContentEncoding() != null && !response.containsHeader("Content-Encoding")) {
            response.addHeader(entity.getContentEncoding());
         }
      } else {
         int status = response.getStatusLine().getStatusCode();
         if (status != 204 && status != 304 && status != 205) {
            response.addHeader("Content-Length", "0");
         }
      }

   }
}
