package org.gcube.application.geoportal.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@Slf4j
public class Files {


	public static Map<String, List<File>> getAllShapeSet(File baseFolder,boolean recursive) throws IOException {
		return clusterizeFilesByExtension(baseFolder,".shp",recursive);
	}

	/*
        Map shpAbsolutePath -> fileset

     */
	public static Map<String, List<File>> clusterizeFilesByExtension(File base,String extension,Boolean recursive) throws IOException {
		HashMap<String,List<File>> toReturn = new HashMap<>();
		log.debug("Clustering "+base.getAbsolutePath());
		List<File> targetFiles=new ArrayList<>();

		// Identify shps
		if(base.isDirectory()){
			// Get all shps
			targetFiles.addAll(Arrays.asList(base.listFiles((dir, name)->{return name.endsWith(extension);})));
			// recursive
			if(recursive)
				for(File f : base.listFiles((dir,name)-> {return new File(dir,name).isDirectory();}))
					toReturn.putAll(clusterizeFilesByExtension(f,extension,recursive));
		}else {
			targetFiles.add(base);
		}

		// Group files by shps
		targetFiles.forEach(f->{
			String basename=f.getName().substring(0,f.getName().lastIndexOf("."));
			toReturn.put(f.getAbsolutePath(),getSiblings(f.getParentFile(),basename));
		});

		return toReturn;
	}


	public static List<File> getSiblings(File location,String baseName){
		List<File> fileset=new ArrayList<>();
		for (File shpSet : location.listFiles((dir, name) -> {return name.startsWith(baseName);}))
			fileset.add(shpSet);
		return fileset;
	}

	public static File getFileFromResources(String fileName) {

        ClassLoader classLoader =Files.class.getClassLoader();

        URL resource = classLoader.getResource(fileName);
        if (resource == null) {
            throw new IllegalArgumentException("file is not found!");
        } else {
            return new File(resource.getFile());
        }

    }	


	public static String readFileAsString(String path, Charset encoding) 
			  throws IOException 
	{
	  byte[] encoded = java.nio.file.Files.readAllBytes(Paths.get(path));
	  return new String(encoded, encoding);
	}
	
	
	public static String getName(String path) {
		
		return path.substring((path.contains(File.separator)?path.lastIndexOf(File.separator)+1:0)
				,(path.contains(".")?path.lastIndexOf("."):path.length()));
		
	}
	
	public static String fixFilename(String toFix) {
		if(toFix.startsWith("\\."))
			toFix=toFix.replaceFirst("\\.","_");
		String extension="";
		if(toFix.contains(".")) {
			//preserve extension
			int index=toFix.indexOf(".");
			extension=toFix.substring(index);
			//only escape before extension
			toFix=toFix.substring(0,toFix.indexOf("."));
		}
		return toFix.toLowerCase().
				replaceAll("[\\-\\*\\+\\/\\\\ \\[\\]\\(\\)\\.\\\"\\:\\;\\|\\=]","_")+extension;
	}

	public static final File downloadFromUrl(String name,String url) throws IOException {
		Path dest =java.nio.file.Files.createTempDirectory("downloads_").resolve(name);
		InputStream is = null;
		try {
			java.nio.file.Files.copy(new URL(url).openStream(), dest);
			return dest.toFile();
		}finally {
			if(is!=null) IOUtils.closeQuietly(is);
		}
	}
}
