package mara.mybox.tools;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import mara.mybox.data.FileSynchronizeAttributes;
import mara.mybox.dev.MyBoxLog;
import mara.mybox.fxml.FxTask;
import static mara.mybox.value.Languages.message;

/**
 * @Author Mara
 * @CreateDate 2021-8-1
 * @License Apache License Version 2.0
 */
public class FileCopyTools {

    public static boolean copyFile(String sourceFile, String targetFile) {
        return copyFile(new File(sourceFile), new File(targetFile));
    }

    public static boolean copyFile(File sourceFile, File targetFile) {
        return copyFile(sourceFile, targetFile, false, true);
    }

    public static boolean copyFile(File sourceFile, File targetFile, boolean isCanReplace, boolean isCopyAttrinutes) {
        try {
            if (sourceFile == null || !sourceFile.isFile() || !sourceFile.exists()) {
                return false;
            }
            if (isCanReplace) {
                if (isCopyAttrinutes) {
                    Files.copy(Paths.get(sourceFile.getAbsolutePath()), Paths.get(targetFile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
                } else {
                    Files.copy(Paths.get(sourceFile.getAbsolutePath()), Paths.get(targetFile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING);
                }
            } else {
                if (isCopyAttrinutes) {
                    Files.copy(Paths.get(sourceFile.getAbsolutePath()), Paths.get(targetFile.getAbsolutePath()), StandardCopyOption.COPY_ATTRIBUTES);
                } else {
                    Files.copy(Paths.get(sourceFile.getAbsolutePath()), Paths.get(targetFile.getAbsolutePath()));
                }
            }
            return true;
        } catch (Exception e) {
            MyBoxLog.error(e + "\n" + "Source:" + sourceFile + "\n" + "Target:" + targetFile);
            return false;
        }
    }

    public static boolean copyFile(File sourceFile, File targetFile, FileSynchronizeAttributes attr) {
        if (attr == null) {
            attr = new FileSynchronizeAttributes();
        }
        return copyFile(sourceFile, targetFile, attr.isCanReplace(), attr.isCopyAttrinutes());
    }

    public static FileSynchronizeAttributes copyWholeDirectory(FxTask task,
            File sourcePath, File targetPath) {
        FileSynchronizeAttributes attr = new FileSynchronizeAttributes();
        copyWholeDirectory(task, sourcePath, targetPath, attr);
        return attr;
    }

    public static boolean copyWholeDirectory(FxTask task,
            File sourcePath, File targetPath, FileSynchronizeAttributes attr) {
        return copyWholeDirectory(task, sourcePath, targetPath, attr, true);
    }

    public static boolean copyWholeDirectory(FxTask task, File sourcePath, File targetPath, FileSynchronizeAttributes attr, boolean clearTarget) {
        try {
            if (sourcePath == null || !sourcePath.exists() || !sourcePath.isDirectory()) {
                return false;
            }
            if (FileTools.isEqualOrSubPath(targetPath.getAbsolutePath(), sourcePath.getAbsolutePath())) {
                MyBoxLog.error(message("TreeTargetComments"));
                return false;
            }
            if (attr == null) {
                attr = new FileSynchronizeAttributes();
            }
            if (targetPath.exists()) {
                if (clearTarget && !FileDeleteTools.deleteDir(task, targetPath)) {
                    return false;
                }
            } else {
                targetPath.mkdirs();
            }
            File[] files = sourcePath.listFiles();
            if (files == null) {
                return false;
            }
            for (File file : files) {
                if (task != null && !task.isWorking()) {
                    return false;
                }
                File targetFile = new File(targetPath + File.separator + file.getName());
                if (file.isFile()) {
                    if (copyFile(file, targetFile, attr)) {
                        attr.setCopiedFilesNumber(attr.getCopiedFilesNumber() + 1);
                    } else if (!attr.isContinueWhenError()) {
                        return false;
                    }
                } else if (file.isDirectory()) {
                    if (copyWholeDirectory(task, file, targetFile, attr, clearTarget)) {
                        attr.setCopiedDirectoriesNumber(attr.getCopiedDirectoriesNumber() + 1);
                    } else if (!attr.isContinueWhenError()) {
                        return false;
                    }
                }
            }
            return true;
        } catch (Exception e) {
            MyBoxLog.error(e.toString());
            return false;
        }
    }

}
