/*
 * Copyright (C) 2013 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.okhttp;

import com.squareup.okhttp.internal.NamedRunnable;
import com.squareup.okhttp.internal.http.HttpAuthenticator;
import com.squareup.okhttp.internal.http.HttpEngine;
import com.squareup.okhttp.internal.http.HttpURLConnectionImpl;
import com.squareup.okhttp.internal.http.OkHeaders;
import java.io.IOException;
import java.io.InputStream;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

import static com.squareup.okhttp.internal.Util.getEffectivePort;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MOVED_PERM;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MOVED_TEMP;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MULT_CHOICE;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_PROXY_AUTH;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_SEE_OTHER;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_UNAUTHORIZED;
import static com.squareup.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;

final class Job extends NamedRunnable {
  private final Dispatcher dispatcher;
  private final OkHttpClient client;
  private final Response.Receiver responseReceiver;
  private int redirectionCount;

  volatile boolean canceled;

  /** The request; possibly a consequence of redirects or auth headers. */
  private Request request;
  HttpEngine engine;

  public Job(Dispatcher dispatcher, OkHttpClient client, Request request,
      Response.Receiver responseReceiver) {
    super("OkHttp %s", request.urlString());
    this.dispatcher = dispatcher;
    this.client = client;
    this.request = request;
    this.responseReceiver = responseReceiver;
  }

  String host() {
    return request.url().getHost();
  }

  Request request() {
    return request;
  }

  Object tag() {
    return request.tag();
  }

  @Override protected void execute() {
    try {
      Response response = getResponse();
      if (response != null && !canceled) {
        responseReceiver.onResponse(response);
      }
    } catch (IOException e) {
      responseReceiver.onFailure(new Failure.Builder()
          .request(request)
          .exception(e)
          .build());
    } finally {
      engine.close(); // Close the connection if it isn't already.
      dispatcher.finished(this);
    }
  }

  /**
   * Performs the request and returns the response. May return null if this job
   * was canceled.
   */
  Response getResponse() throws IOException {
    Response redirectedBy = null;

    // Copy body metadata to the appropriate request headers.
    Request.Body body = request.body();
    if (body != null) {
      MediaType contentType = body.contentType();
      if (contentType == null) throw new IllegalStateException("contentType == null");

      Request.Builder requestBuilder = request.newBuilder();
      requestBuilder.header("Content-Type", contentType.toString());

      long contentLength = body.contentLength();
      if (contentLength != -1) {
        requestBuilder.header("Content-Length", Long.toString(contentLength));
        requestBuilder.removeHeader("Transfer-Encoding");
      } else {
        requestBuilder.header("Transfer-Encoding", "chunked");
        requestBuilder.removeHeader("Content-Length");
      }

      request = requestBuilder.build();
    }

    // Create the initial HTTP engine. Retries and redirects need new engine for each attempt.
    engine = new HttpEngine(client, request, false, null, null, null, null);

    while (true) {
      if (canceled) return null;

      try {
        engine.sendRequest();

        if (body != null) {
          BufferedSink sink = Okio.buffer(engine.getRequestBody());
          body.writeTo(sink);
          sink.flush();
        }

        engine.readResponse();
      } catch (IOException e) {
        HttpEngine retryEngine = engine.recover(e);
        if (retryEngine != null) {
          engine = retryEngine;
          continue;
        }

        // Give up; recovery is not possible.
        throw e;
      }

      Response response = engine.getResponse();
      Request redirect = processResponse(engine, response);

      if (redirect == null) {
        engine.releaseConnection();
        return response.newBuilder()
            .body(new RealResponseBody(response, engine.getResponseBody()))
            .priorResponse(redirectedBy)
            .build();
      }

      if (!sameConnection(request, redirect)) {
        engine.releaseConnection();
      }

      Connection connection = engine.close();
      redirectedBy = response.newBuilder().priorResponse(redirectedBy).build(); // Chained.
      request = redirect;
      engine = new HttpEngine(client, request, false, connection, null, null, null);
    }
  }

  /**
   * Figures out the HTTP request to make in response to receiving {@code
   * response}. This will either add authentication headers or follow
   * redirects. If a follow-up is either unnecessary or not applicable, this
   * returns null.
   */
  private Request processResponse(HttpEngine engine, Response response) throws IOException {
    Request request = response.request();
    Proxy selectedProxy = engine.getRoute() != null
        ? engine.getRoute().getProxy()
        : client.getProxy();
    int responseCode = response.code();

    switch (responseCode) {
      case HTTP_PROXY_AUTH:
        if (selectedProxy.type() != Proxy.Type.HTTP) {
          throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
        }
        // fall-through
      case HTTP_UNAUTHORIZED:
        return HttpAuthenticator.processAuthHeader(
            client.getAuthenticator(), response, selectedProxy);

      case HTTP_MULT_CHOICE:
      case HTTP_MOVED_PERM:
      case HTTP_MOVED_TEMP:
      case HTTP_SEE_OTHER:
      case HTTP_TEMP_REDIRECT:
        if (!client.getFollowProtocolRedirects()) {
          return null; // This client has is configured to not follow redirects.
        }

        if (++redirectionCount > HttpURLConnectionImpl.MAX_REDIRECTS) {
          throw new ProtocolException("Too many redirects: " + redirectionCount);
        }

        String method = request.method();
        if (responseCode == HTTP_TEMP_REDIRECT && !method.equals("GET") && !method.equals("HEAD")) {
          // "If the 307 status code is received in response to a request other than GET or HEAD,
          // the user agent MUST NOT automatically redirect the request"
          return null;
        }

        String location = response.header("Location");
        if (location == null) {
          return null;
        }

        URL url = new URL(request.url(), location);
        if (!url.getProtocol().equals("https") && !url.getProtocol().equals("http")) {
          return null; // Don't follow redirects to unsupported protocols.
        }

        return this.request.newBuilder().url(url).build();

      default:
        return null;
    }
  }

  static boolean sameConnection(Request a, Request b) {
    return a.url().getHost().equals(b.url().getHost())
        && getEffectivePort(a.url()) == getEffectivePort(b.url())
        && a.url().getProtocol().equals(b.url().getProtocol());
  }

  static class RealResponseBody extends Response.Body {
    private final Response response;
    private final Source source;

    /** Multiple calls to {@link #byteStream} must return the same instance. */
    private InputStream in;

    RealResponseBody(Response response, Source source) {
      this.response = response;
      this.source = source;
    }

    @Override public boolean ready() throws IOException {
      return true;
    }

    @Override public MediaType contentType() {
      String contentType = response.header("Content-Type");
      return contentType != null ? MediaType.parse(contentType) : null;
    }

    @Override public long contentLength() {
      return OkHeaders.contentLength(response);
    }

    @Override public Source source() {
      return source;
    }

    @Override public InputStream byteStream() {
      InputStream result = in;
      return result != null
          ? result
          : (in = Okio.buffer(source).inputStream());
    }
  }
}
