package org.ccci.gto.android.common.util;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;

public final class IOUtils {
    // 640K should be enough for anybody -Bill Gates
    // (Bill Gates never actually said this)
    private static final int DEFAULT_BUFFER_SIZE = 640 * 1024;
    private static final int EOF = -1;

    public static void closeQuietly(@Nullable final Closeable handle) {
        if (handle != null) {
            try {
                handle.close();
            } catch (final IOException e) {
                // suppress the error
            }
        }
    }

    public static void closeQuietly(@Nullable final HttpURLConnection conn) {
        if (conn != null) {
            conn.disconnect();
        }
    }

    public static long copy(@NonNull final InputStream in, @NonNull final OutputStream out) throws IOException {
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        long count = 0;
        int n;
        while (EOF != (n = in.read(buffer))) {
            out.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

    @NonNull
    public static String readString(@NonNull final InputStream in) throws IOException {
        final BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"), DEFAULT_BUFFER_SIZE);
        final StringBuilder out = new StringBuilder();
        final char[] buffer = new char[DEFAULT_BUFFER_SIZE];
        int n;
        while (EOF != (n = reader.read(buffer, 0, buffer.length))) {
            out.append(buffer, 0, n);
        }
        return out.toString();
    }
}

@@ -1090,32 +1090,259 @@
 s IOException %7B%0A
+        return copy(in, out, null);%0A    %7D%0A%0A    public static long copy(@NonNull final InputStream in, @NonNull final OutputStream out,%0A                            @Nullable final ProgressCallback progress) throws IOException %7B%0A
         byte%5B%5D b
@@ -1372,32 +1372,32 @@
 T_BUFFER_SIZE%5D;%0A
-
         long cou
@@ -1523,24 +1523,116 @@
 count += n;%0A
+            if (progress != null) %7B%0A                progress.progress(count);%0A            %7D%0A
         %7D%0A  
@@ -2114,32 +2114,32 @@
 , n);%0A        %7D%0A
-
         return o
@@ -2158,11 +2158,93 @@
 );%0A    %7D
+%0A%0A    public interface ProgressCallback %7B%0A        void progress(long count);%0A    %7D
 %0A%7D%0A

add support for a progress callback during IOUtils.copy