package com.input.board.appskey.keyboard.fileTools;

import com.input.board.appskey.keyboard.KeyBoardApp;
import com.input.board.appskey.keyboard.interf.onApplyCallback;

import net.sf.sevenzipjbinding.ArchiveFormat;
import net.sf.sevenzipjbinding.IArchiveOpenCallback;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class DownloadZip {

    public static void startDownloadZip(String zipPath, onApplyCallback callback) {
        OkHttpClient clientZip = new OkHttpClient().newBuilder().
                connectTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS).build();
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url(zipPath).build();

        clientZip.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onApplyResult(null);
            }

            @Override
            public void onResponse(Call call, Response response) {

                InputStream inputStream = response.body().byteStream();
                long l = response.body().contentLength();
                MediaType mediaType = response.body().contentType();

                saveZipFile(inputStream, getServiceZipName(zipPath),callback);

            }
        });
    }


    private static String getServiceZipName(String zipPath) {
        String pointStr = "/";
        int lastIndexOf = zipPath.lastIndexOf(pointStr);
        String zipName = zipPath.substring(lastIndexOf + pointStr.length());


        return zipName;
    }

    private static String getunZipFolderName(String zipPath) {
        String pointStr = ".";
        int lastIndexOf = zipPath.lastIndexOf(pointStr);
        String zipName = zipPath.substring(0, lastIndexOf);


        return zipName;
    }

    private static void saveZipFile(InputStream inputStream, String zipFileName,onApplyCallback callback) {
        File zipfFile = new File(KeyBoardApp.appInstance.getFilesDir(), zipFileName);
        byte[] bytes = new byte[4096];
        int readLength = 0;
        InputStream is = inputStream;
        FileOutputStream fileOs = null;
        try {
            fileOs = new FileOutputStream(zipfFile);

            while ((readLength = is.read(bytes)) != -1) {
                fileOs.write(bytes, 0, readLength);
            }
            fileOs.flush();

        } catch (Exception exception) {

        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (fileOs != null) {
                    fileOs.close();
                }
            } catch (IOException ioException) {

            }
            un7ZZipFile(zipfFile,callback);
        }

    }

    private static void un7ZZipFile(File saveZipFile,onApplyCallback callback) {
        List<File> fileList = new ArrayList<>();
        String folderName = getunZipFolderName(saveZipFile.getName());
        String replace = folderName.replace(".", "");
        String unzipFolderPath = KeyBoardApp.appInstance.getFilesDir().getPath()+"/"+replace;
        try {
            RandomAccessFileInStream inStream = new RandomAccessFileInStream(new RandomAccessFile(saveZipFile, "r"));
            IInArchive open = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, inStream, new IArchiveOpenCallback() {
                @Override
                public void setTotal(Long files, Long bytes) {

                }

                @Override
                public void setCompleted(Long files, Long bytes) {

                }
            });


            ISimpleInArchive simple = open.getSimpleInterface();
            for (ISimpleInArchiveItem archiveItem : simple.getArchiveItems()) {
                RandomAccessFileOutStream outStream = null;
                try {
                    File itemFile;
                    if (archiveItem.isFolder()) {
                        File itemFolder = new File(unzipFolderPath, archiveItem.getPath());
                        boolean mkdirs = itemFolder.mkdirs();
                        continue;
                    } else {
                        itemFile = new File(unzipFolderPath, archiveItem.getPath());
                        if (!itemFile.getParentFile().exists()) {
                            boolean mkdirs = itemFile.getParentFile().mkdirs();
                        }
                    }
                    outStream = new RandomAccessFileOutStream(new RandomAccessFile(itemFile, "rw"));
                    archiveItem.extractSlow(outStream);
                    fileList.add(itemFile);
                } finally {
                    if (outStream != null) {
                        outStream.close();
                    }
                }
            }



            inStream.close();
            open.close();

        } catch (FileNotFoundException | SevenZipException exception) {

        } catch (IOException ioException) {

        }finally {
            callback.onApplyResult(fileList);
        }
    }



}
