package xyz.ttnaarashi.mc.autoUpdate.utils;

import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import lombok.Cleanup;
import lombok.val;
import org.apache.logging.log4j.Logger;

import javax.net.ssl.HttpsURLConnection;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;

import static xyz.ttnaarashi.mc.autoUpdate.utils.DEBUG.QUICK_DEBUG;

public final class QuickMethod {
    public static void debugOrWarn(Logger logger, String info) {
        if (QUICK_DEBUG)
            logger.warn(info);
        else
            logger.debug(info);
    }

    public static File getCacheDir(Boolean clean) {
        return getDir(clean, "MC_AutoUpdate_TEMP");
    }

    private static File getDir(Boolean clean, String childPath) {
        val dir = new File(getMCRootDir(), childPath);
        if (!dir.isDirectory())
            dir.delete();
        if (clean)
            deleteDir(dir);
        if (!dir.exists())
            dir.mkdirs();

        return dir;
    }

    public static File getCacheDir() {
        return getCacheDir(false);
    }

    public static File getOldAUDir() {
        return getOldAUDir(false);
    }

    public static File getOldAUDir(boolean clean) {
        return getDir(clean, "MC_AutoUpdate_OLD");
    }

    public static File getModListFile() throws IOException {
        val modList = new File(getMCRootDir(), "modList.json");
        if (!modList.exists()) modList.createNewFile();
        return modList;
    }

    public static File getMCRootDir() {
        return new File(System.getProperty("user.dir"));
    }

    public static boolean deleteDir(File dir) {
        if (!dir.exists()) return false;
        if (dir.isDirectory()) {
            String[] childrens = dir.list();

            for (String child : childrens) {
                boolean success = deleteDir(new File(dir, child));
                if (!success) return false;
            }
        }
        return dir.delete();
    }

    public static Optional<HashCode> getSHA256(final File file) {
        HashCode code = null;
        if (file == null) return Optional.empty();
        try {
            code = Files.asByteSource(file).hash(Hashing.sha256());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Optional.ofNullable(code);
    }

    public static HttpsURLConnection getConnection(URL link) throws IOException {
        val connection = (HttpsURLConnection) link.openConnection();
        connection.setHostnameVerifier((name, socket) -> true);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0");
        connection.setRequestProperty("Connection", "close");
        return connection;
    }

    public static boolean copyFile(File from, File to) {
        long ctn = 0;
        long total = -1;
        try {
            @Cleanup val input = new FileInputStream(from).getChannel();
            total = input.size();
            @Cleanup val output = new FileOutputStream(to).getChannel();
            ctn = output.transferFrom(input, 0, total);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return total == ctn;
    }
}
