/*
 * 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.picasso3;

import android.net.NetworkInfo;
import java.io.IOException;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.Response;
import okhttp3.ResponseBody;

import static com.squareup.picasso3.Picasso.LoadedFrom.DISK;
import static com.squareup.picasso3.Picasso.LoadedFrom.NETWORK;

final class NetworkRequestHandler extends RequestHandler {
  private static final String SCHEME_HTTP = "http";
  private static final String SCHEME_HTTPS = "https";

  private final Call.Factory callFactory;
  private final Stats stats;

  NetworkRequestHandler(Call.Factory callFactory, Stats stats) {
    this.callFactory = callFactory;
    this.stats = stats;
  }

  @Override public boolean canHandleRequest(Request data) {
    String scheme = data.uri.getScheme();
    return (SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme));
  }

  @Override public void load(Request request, int networkPolicy, Callback callback) {
    boolean signaledCallback = false;
    try {
      okhttp3.Request callRequest = createRequest(request, networkPolicy);
      Response response = callFactory.newCall(callRequest).execute();
      if (!response.isSuccessful()) {
        signaledCallback = true;
        callback.onError(new ResponseException(response.code(), request.networkPolicy));
        return;
      }

      // Cache response is only null when the response comes fully from the network. Both completely
      // cached and conditionally cached responses will have a non-null cache response.
      Picasso.LoadedFrom loadedFrom = response.cacheResponse() == null ? NETWORK : DISK;

      // Sometimes response content length is zero when requests are being replayed. Haven't found
      // root cause to this but retrying the request seems safe to do so.
      ResponseBody body = response.body();
      if (loadedFrom == DISK && body.contentLength() == 0) {
        body.close();
        signaledCallback = true;
        callback.onError(
            new ContentLengthException("Received response with 0 content-length header."));
        return;
      }
      if (loadedFrom == NETWORK && body.contentLength() > 0) {
        stats.dispatchDownloadFinished(body.contentLength());
      }
      signaledCallback = true;
      callback.onSuccess(new Result(body.source(), loadedFrom));
    } catch (IOException e) {
      if (!signaledCallback) {
        callback.onError(e);
      }
    }
  }

  @Override int getRetryCount() {
    return 2;
  }

  @Override boolean shouldRetry(boolean airplaneMode, NetworkInfo info) {
    return info == null || info.isConnected();
  }

  @Override boolean supportsReplay() {
    return true;
  }

  private static okhttp3.Request createRequest(Request request, int networkPolicy) {
    CacheControl cacheControl = null;
    if (networkPolicy != 0) {
      if (NetworkPolicy.isOfflineOnly(networkPolicy)) {
        cacheControl = CacheControl.FORCE_CACHE;
      } else {
        CacheControl.Builder builder = new CacheControl.Builder();
        if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) {
          builder.noCache();
        }
        if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) {
          builder.noStore();
        }
        cacheControl = builder.build();
      }
    }

    okhttp3.Request.Builder builder = new okhttp3.Request.Builder().url(request.uri.toString());
    if (cacheControl != null) {
      builder.cacheControl(cacheControl);
    }
    return builder.build();
  }

  static class ContentLengthException extends IOException {
    ContentLengthException(String message) {
      super(message);
    }
  }

  static final class ResponseException extends IOException {
    final int code;
    final int networkPolicy;

    ResponseException(int code, int networkPolicy) {
      super("HTTP " + code);
      this.code = code;
      this.networkPolicy = networkPolicy;
    }
  }
}

@@ -1493,16 +1493,22 @@
 id load(
+final 
 Request 
@@ -1534,16 +1534,22 @@
 kPolicy,
+ final
  Callbac
@@ -1566,58 +1566,8 @@
 ) %7B%0A
-    boolean signaledCallback = false;%0A    try %7B%0A  
     
@@ -1642,30 +1642,8 @@
 %0A   
-   Response response =
  cal
@@ -1677,18 +1677,113 @@
 t).e
-xecute();%0A
+nqueue(new okhttp3.Callback() %7B%0A      @Override public void onResponse(Call call, Response response) %7B%0A  
     
@@ -1822,39 +1822,8 @@
 %7B%0A  
-      signaledCallback = true;%0A
     
@@ -1907,32 +1907,34 @@
 licy));%0A        
+  
 return;%0A      %7D%0A
@@ -1927,24 +1927,26 @@
 turn;%0A      
+  
 %7D%0A%0A      // 
@@ -1942,16 +1942,18 @@
 %0A%0A      
+ 
+ 
 // Cache
@@ -2027,16 +2027,27 @@
 rk. Both
+%0A        //
  complet
@@ -2049,25 +2049,16 @@
 mpletely
-%0A      //
  cached 
@@ -2129,16 +2129,18 @@
 sponse.%0A
+  
       Pi
@@ -2221,16 +2221,18 @@
  DISK;%0A%0A
+  
       //
@@ -2328,16 +2328,18 @@
 d%0A      
+  
 // root 
@@ -2400,24 +2400,26 @@
 o so.%0A      
+  
 ResponseBody
@@ -2439,24 +2439,26 @@
 nse.body();%0A
+  
       if (lo
@@ -2514,16 +2514,18 @@
         
+  
 body.clo
@@ -2536,39 +2536,8 @@
 ;%0A  
-      signaledCallback = true;%0A
     
@@ -2558,16 +2558,18 @@
 nError(%0A
+  
         
@@ -2652,32 +2652,34 @@
 er.%22));%0A        
+  
 return;%0A      %7D%0A
@@ -2672,26 +2672,30 @@
 turn;%0A      
+ 
+ 
 %7D%0A
+  
       if (lo
@@ -2753,16 +2753,18 @@
         
+  
 stats.di
@@ -2819,41 +2819,14 @@
     
+ 
+ 
 %7D%0A  
-    signaledCallback = true;%0A
     
@@ -2894,61 +2894,75 @@
     
-%7D catch (IOException e) %7B%0A      if (!signaledCallback
+  %7D%0A%0A      @Override public void onFailure(Call call, IOException e
 ) %7B%0A
@@ -2999,24 +2999,26 @@
      %7D%0A    %7D
+);
 %0A  %7D%0A%0A  @Ove

Use OkHttp.enqueue vs execute