package kz.arta.synergy.workflow.mobile.android.files.manager;

import android.util.Base64;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.common.utils.Logger;

/**
 * Created by neox on 11.04.14.
 * Заливка файла на сервер
 */
public class UploadFile {

    public static final String INBOX_FILE = "ase:attachmentContainer";
    public static final String WORK_FILE = "ase:workContainer";

    private Person person;
    private String container;
    private boolean addToWork;

    public UploadFile(Person person, boolean addToWork, String container) {
        this.person = person;
        this.addToWork = addToWork;
        this.container = container;
    }

    /**
     * Метод добавляет файл к работе либо документу
     * Принимает на вход 3 параметра: UUID работы/документа, имя файла и абсолютный путь до файла
     * Метод состоит из трех частей:
     * 1: первый запрос для получения пути к временному файлу
     * 2: загрузка файла по частям
     * 3: добавление файла к работе
     *
     * @param uuid           - ID работы/документа
     * @param attachmentName - имя вложения
     * @param filePath       - абсолютный путь до добавляемого файла
     * @param work           - добавляем файл к документу или к работе
     * @return - сообщение об успешном либо неуспешном выполнении
     */
    public String uploadFile(String uuid, String attachmentName, String filePath, boolean work) {
        try {
            String tmpFilePath;
            URL url = new URL(person.getHost() + "rest/api/storage/start_upload?locale=ru");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/json; charset=utf-8");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Cache-Control", "no-cache");
            String basicAuth = "Basic " + new String(Base64.encode(person.getAuth().getBytes(), Base64.NO_WRAP));
            conn.setRequestProperty("Authorization", basicAuth);
            String output;
            StringBuilder contactsInfo = new StringBuilder();
            BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
            while ((output = br.readLine()) != null) {
                contactsInfo.append(output);
            }
            conn.disconnect();
            FileUpload fileUpload = RestClient.getGson().fromJson(contactsInfo.toString(), FileUpload.class);
            tmpFilePath = fileUpload.file;
            String boundary = "qweasdzxczxcasdqwe";
            String crlf = "\r\n";
            String twoHyphens = "--";
            FileInputStream fin = new FileInputStream(filePath);
            int partSize = 1024 * 100;
            byte[] bytes = new byte[partSize];
            int position = 0;
            int read = 0;
            while ((read = fin.read(bytes, 0, partSize)) != -1) {
                byte[] readBytes = new byte[read];
                System.arraycopy(bytes, 0, readBytes, 0, read);
                position += read;
                url = new URL(person.getHost() + "rest/api/storage/upload_part?file=" + URLEncoder.encode(tmpFilePath, "utf-8"));
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Accept", "application/json; charset=utf-8");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("Cache-Control", "no-cache");
                basicAuth = "Basic " + new String(Base64.encode(person.getAuth().getBytes(), Base64.NO_WRAP));
                conn.setRequestProperty("Authorization", basicAuth);
                conn.setUseCaches(false);
                conn.setDoInput(true);
                conn.setDoOutput(true);
                DataOutputStream request = new DataOutputStream(conn.getOutputStream());
                request.writeBytes(twoHyphens + boundary + crlf);
                request.writeBytes("Content-Disposition: form-data; name=\"body\";filename=\"" + URLEncoder.encode(attachmentName, "utf-8") + "\"" + crlf);
                request.writeBytes(crlf);
                request.write(Base64.encode(bytes, Base64.NO_WRAP));
                request.writeBytes(crlf);
                request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
                request.flush();
                request.close();
                InputStream is = conn.getInputStream();
                BufferedReader rd = new BufferedReader(new InputStreamReader(is));
                String line;
                StringBuilder response = new StringBuilder();
                while ((line = rd.readLine()) != null) {
                    response.append(line);
                    response.append('\r');
                }
                rd.close();
            }
            if (addToWork) {
                return tmpFilePath;
            } else {
                String u;
                if (work) {
                    u = person.getHost() + "rest/api/workflow/work/" + uuid + "/attachment/create";
                } else {
                    u = person.getHost() + "rest/api/docflow/doc/attachment/create";
                }
                url = new URL(u);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Accept", "application/json; charset=utf-8");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("Cache-Control", "no-cache");
                basicAuth = "Basic " + new String(Base64.encode(person.getAuth().getBytes(), Base64.NO_WRAP));
                conn.setRequestProperty("Authorization", basicAuth);
                conn.setUseCaches(false);
                conn.setDoInput(true);
                conn.setDoOutput(true);
                DataOutputStream request = new DataOutputStream(conn.getOutputStream());
                Logger.v("attachmentName = " + attachmentName);
                request.writeBytes("fileName=" + URLEncoder.encode(attachmentName, "utf-8") + "&");
                request.writeBytes("filePath=" + URLEncoder.encode(tmpFilePath, "utf-8") + "&");
                request.writeBytes("path=" + URLEncoder.encode(container, "utf-8") + "&");
                request.writeBytes("documentID=" + URLEncoder.encode(uuid, "utf-8") + "&");
                request.flush();
                request.close();
                InputStream is = conn.getInputStream();
                BufferedReader rd = new BufferedReader(new InputStreamReader(is));
                String line;
                StringBuilder response = new StringBuilder();
                while ((line = rd.readLine()) != null) {
                    response.append(line);
                    response.append('\r');
                }
                rd.close();
                return response.toString();
            }
        } catch (Exception exc) {
            return null;
        }
    }

    class FileUpload {
        String file;
    }
}