package net.northking.cctp.element.scanner;

import net.northking.cctp.element.core.scanner.LibraryDefinition;
import net.northking.cctp.element.core.scanner.ResourceScanner;
import net.northking.cctp.element.util.Assert;
import net.northking.cctp.element.util.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.NoSuchFileException;
import java.util.UUID;

/**
 * LibraryLoadHelper
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class LibraryLoadHelper {

    protected static Logger logger = LoggerFactory.getLogger(LibraryLoadHelper.class);

    /**
     * 加载组件库jar包,提取库相关信息
     *
     * @param jarSource
     * @return LibraryDefinition
     * @throws Exception
     */
    public static LibraryDefinition load(Object jarSource) throws Exception {
        Assert.notNull(jarSource);
        logger.debug("------ 加载组件库资源开始 ------");
        JarResourceProvider provider = new JarResourceProvider();
        provider.add(getLocalJarURL(jarSource));
        provider.initialize();
        logger.debug("------ 加载组件库资源结束 ------");
        /** scan resources to create library definition **/
        ResourceScanner scanner = new ResourceScanner();
        scanner.setResourceLoader(provider);
        return scanner.doScan();
    }

    private static URL getLocalJarURL(Object source) throws Exception {
        if (source instanceof URL) {
            URL url = (URL) source;
            try {
                File file = new File(url.toURI());
                if (file.exists() && file.isFile()) {
                    return url;
                } else {
                    throw new NoSuchFileException("File does not exist");
                }
            } catch (Exception e) {
                InputStream is = url.openStream();
                return writeJarFile(is);
            }
        } else if (source instanceof String) {
            File file = new File((String) source);
            if (file.exists() && file.isFile()) {
                return file.toURI().toURL();
            }
            throw new NoSuchFileException("File does not exist");
        } else if (source instanceof InputStream) {
            return writeJarFile((InputStream) source);
        } else {
            throw new Exception("Unknown Resource type");
        }
    }

    private static URL writeJarFile(InputStream is) throws Exception {
        String jarName = UUID.randomUUID().toString().replace("-", "") + ".jar";
        String root = SystemUtils.getUserHome().getPath();
        root = StringUtils.removeEnd(root, File.separator);
        File file = FileUtils.writeFile(is, String.format("%s/%s", root, jarName));
        return file.toURI().toURL();
    }
}