package com.qiniu.android.storage;

import com.qiniu.android.common.Config;
import com.qiniu.android.http.CompletionHandler;
import com.qiniu.android.http.HttpManager;
import com.qiniu.android.http.PostArgs;
import com.qiniu.android.http.ProgressHandler;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.utils.Crc32;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 *  表单上传
 *
 *  通过表单，你可以将一个图片或者一个文本文件等上传到七牛服务器。这个表单
 *  就是标准的http表单，即<code>enctype="multipart/form-data"</code>
 *  格式的表单。
 */
final class FormUploader {

    /**
     *  上传数据，并以指定的key保存文件
     *
     *  @param httpManager          HTTP连接管理器
     *  @param data                 上传的数据
     *  @param key                  上传的数据保存的文件名
     *  @param token                上传凭证
     *  @param completionHandler    上传完成后续处理动作
     *  @param options              上传时的可选参数
     */
    static void upload(HttpManager httpManager, byte[] data, String key, String token, final UpCompletionHandler completionHandler,
                       final UploadOptions options) {
        post(data, null, key, token, completionHandler, options, httpManager);
    }

    /**
     *  上传文件，并以指定的key保存文件
     *
     *  @param httpManager          HTTP连接管理器
     *  @param file                 上传的文件
     *  @param key                  上传的数据保存的文件名
     *  @param token                上传凭证
     *  @param completionHandler    上传完成后续处理动作
     *  @param options              上传时的可选参数
     */
    static void upload(HttpManager httpManager, File file, String key, String token, UpCompletionHandler completionHandler,
                       UploadOptions options) {
        post(null, file, key, token, completionHandler, options, httpManager);
    }

    private static void post(byte[] data, File file, String k, String token, final UpCompletionHandler completionHandler,
                             final UploadOptions options, final HttpManager httpManager) {
        final String key = k;
        Map<String, String> params = new HashMap<String, String>();
        final PostArgs args = new PostArgs();
        if (k != null) {
            params.put("key", key);
            args.fileName = key;
        } else {
            args.fileName = "?";
        }

        params.put("token", token);
        if (options != null) {
            params.putAll(options.params);
        }

        String mimeType = "application/octet-stream";
        if (options != null && options.mimeType != null && options.mimeType.equals("")) {
            mimeType = options.mimeType;
        }

        if (options != null && options.checkCrc) {
            long crc = 0;
            if (file != null) {
                try {
                    crc = Crc32.file(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                crc = Crc32.bytes(data);
            }
            params.put("crc32", "" + crc);
        }


        args.data = data;
        args.file = file;
        args.mimeType = mimeType;
        args.params = params;

        ProgressHandler progress = null;
        if (options != null && options.progressHandler != null) {
            progress = new ProgressHandler() {
                @Override
                public void onProgress(int bytesWritten, int totalSize) {
                    double percent = (double) bytesWritten / (double) totalSize;
                    if (percent > 0.95) {
                        percent = 0.95;
                    }
                    options.progressHandler.progress(key, percent);
                }
            };
        }

        final ProgressHandler progress2 = progress;

        CompletionHandler completion = new CompletionHandler() {
            @Override
            public void complete(ResponseInfo info, JSONObject response) {
                if (info.isOK()) {
                    if (progress2 != null) {
                        options.progressHandler.progress(key, 1.0);
                    }
                    completionHandler.complete(key, info, response);
                    return;
                }
                CompletionHandler retried = new CompletionHandler() {
                    @Override
                    public void complete(ResponseInfo info, JSONObject response) {
                        if (info.isOK() && progress2 != null) {
                            options.progressHandler.progress(key, 1.0);
                        }
                        completionHandler.complete(key, info, response);
                    }
                };
                String host = Config.UP_HOST;
                if (info.isNetworkBroken()) {
                    host = Config.UP_HOST_BACKUP;
                }
                httpManager.multipartPost("http://" + host, args, progress2, retried);
            }
        };

        httpManager.multipartPost("http://" + Config.UP_HOST, args, progress, completion);
    }
}

@@ -2521,32 +2521,33 @@
 Type != null && 
+!
 options.mimeType

Fix the bug of form upload with mime type set but not work.