package cn.reghao.tnb.file.app.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 获取 jar 包内的文件资源
 * 
 * @author reghao
 * @date 2025-11-03 16:05:43
 */
public class JarFileResources {
    /**
     * get a file from the resources folder
     * works everywhere, IDEA, unit test and jar file.
     * 
     * @param
     * @return
     * @date 2025-11-03 16:07:27
     */
    public InputStream getFileFromResourceAsStream(String resourcePath) {
        // The class loader that loaded the class
        ClassLoader classLoader = getClass().getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream(resourcePath);
        // the stream holding the file content
        if (inputStream == null) {
            throw new IllegalArgumentException("file not found! " + resourcePath);
        } else {
            return inputStream;
        }
    }

    /**
     * The resource URL is not working in the JAR
     * If we try to access a file that is inside a JAR,
     * It throws NoSuchFileException (linux), InvalidPathException (Windows)
     * Resource URL Sample: file:java-io.jar!/json/file1.json
     *
     * @param
     * @return
     * @date 2025-11-03 16:16:48
     */
    public File getFileFromResource(String resourcePath) throws URISyntaxException{
        ClassLoader classLoader = getClass().getClassLoader();
        URL resource = classLoader.getResource(resourcePath);
        if (resource == null) {
            throw new IllegalArgumentException("file not found! " + resourcePath);
        } else {
            // failed if files have whitespaces or special characters
            //return new File(resource.getFile());
            return new File(resource.toURI());
        }
    }

    /**
     * Get all paths from a folder that inside the jar file
     * 
     * @param
     * @return
     * @date 2025-11-03 16:07:52
     */
    public List<Path> getPathsFromResourceJar(String folder) throws URISyntaxException, IOException {
        // get path of the current running jar
        String jarPath = getClass().getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .toURI()
                .getPath();
        System.out.println("jar Path :" + jarPath);
        // file walks jar
        URI uri = URI.create("jar:file:" + jarPath);
        List<Path> result;
        try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
            result = Files.walk(fs.getPath(folder))
                    .filter(Files::isRegularFile)
                    .collect(Collectors.toList());
        }
        return result;
    }

    public String getRunningJarPath() {
        URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
        String jarFilePath = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8);
        if (jarFilePath.endsWith(".jar")) {
            jarFilePath = jarFilePath.substring(0, jarFilePath.lastIndexOf("/") + 1);
        }

        File file = new File(jarFilePath);
        return file.getAbsolutePath();
    }
}
