package com.yutou.common.okhttp;

import com.yutou.common.utils.Log;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public abstract class FileCallback<T> implements Callback<FileBody<T>> {

    private static ThreadPoolExecutor executor;
    private final T bean;
    private String savePath;

    public FileCallback(T bean, String savePath) {
        this.bean = bean;
        this.savePath = savePath;
        if (executor == null) {
            executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
        }
    }

    private class DownloadTask implements Runnable {
        private T bean;
        private Headers headers;
        private HttpUrl url;
        private InputStream inputStream;

        public DownloadTask(T bean, Headers headers, HttpUrl url, InputStream inputStream) {
            this.bean = bean;

            this.headers = headers;
            this.url = url;
            this.inputStream = inputStream;
        }

        @Override
        public void run() {
            try {
                Log.i("开始下载");
                File file = new File(savePath);
                onStart(bean);
                if (!file.exists()) {
                    boolean mkdirs = file.getParentFile().mkdirs();
                    Log.i("mkdirs = " + mkdirs);
                }
                FileOutputStream outputStream = new FileOutputStream(file);
                int len;
                long total = 0;
                byte[] bytes = new byte[4096];
                boolean isDownload = true;
                long available = inputStream.available();
                while ((len = inputStream.read(bytes)) != -1 && isDownload) {
                    total += len;
                    outputStream.write(bytes, 0, len);
                    outputStream.flush();
                    isDownload = onDownload(headers, bean, total, available);
                }
                Log.i("下载完成");
                outputStream.close();
            } catch (Exception e) {
                Log.e(e);
                onFailure(bean,e);
            } finally {
                onFinish(bean);
                try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e(e);
                }
            }


        }

    }

    public abstract void onStart(T bean);

    public abstract boolean onDownload(Headers headers, T bean, long len, long total);

    public abstract void onFinish(T bean);

    public abstract void onFailure(T bean, Throwable throwable);

    @Override
    public void onResponse(Call<FileBody<T>> call, Response<FileBody<T>> response) {
        try {
            executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream()));
        } catch (Exception e) {
            Log.e(e);
            onFailure(bean,e);
            call.cancel();
        }
    }

    @Override
    public void onFailure(Call<FileBody<T>> call, Throwable throwable) {
        onFailure(bean, throwable);
        call.cancel();
    }

}
