package org.gcube.portlets.user.gisviewer.server.datafeature.wfs;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.log4j.Logger;
import org.gcube.portlets.user.gisviewer.server.datafeature.wfs.WFSExporter.WFS_TO;
import org.gcube.portlets.user.gisviewer.server.util.CSVReader;
import org.gcube.portlets.user.gisviewer.server.util.FileUtil;


// TODO: Auto-generated Javadoc
/**
 * The Class WFSExporterSystemDir.
 *
 * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy)
 * Apr 27, 2020
 */
public class WFSExporterSystemDir {
	
	//private static final String CATALINA_BASE = "catalina.base";

	public static Logger log = Logger.getLogger(WFSExporterSystemDir.class);
	
	private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
	public static final String WEB_CONTAINER_HOME_ENV_VAR = "WEB_CONTAINER_HOME";
	public static final String SYSTEM_DIR_NAME_TO_GIS_VIEWER_CONFIG = "gis-viewer-config";
	
	public static final String WFS_DATA_EXPORT_CONFIG_FILE = "wfs_data_export_config.csv";
	public static final String WFS_DATA_VIEW_CONFIG_FILE = "wfs_data_view_config.csv";
	
	private static String sysGisViewerPathDir;
	
	static {
		
		
		String absolutePath= null;
		
		try {
			
			String webContainerHome = System.getenv(WEB_CONTAINER_HOME_ENV_VAR);
			log.info("The env var "+WEB_CONTAINER_HOME_ENV_VAR+" is: "+webContainerHome);
	
			if(webContainerHome!=null && !webContainerHome.isEmpty()) {
				log.debug(WEB_CONTAINER_HOME_ENV_VAR + " found as env var, using it as absolute path");
				String toWebContTmpDir = webContainerHome+File.separator+"tmp";
				File webContTmp = new File(toWebContTmpDir);
				if(webContTmp.exists() && webContTmp.isDirectory() && webContTmp.canWrite()) {
					log.debug("The folder "+toWebContTmpDir+" exists and I can write it");
					absolutePath = toWebContTmpDir;
				}else {
					log.debug("Either the folder "+toWebContTmpDir+" does not exist or I cannot write it");
				}
			}
		}catch(Exception e) {
			log.warn("I'm not able to use the env var: "+WEB_CONTAINER_HOME_ENV_VAR);
		}
		
		/*
		String absolutePath= null;
		try {
			String catalinaBaseDir = System.getProperty(CATALINA_BASE);
			log.info(CATALINA_BASE + " is: "+catalinaBaseDir);
	
			if(catalinaBaseDir!=null && !catalinaBaseDir.isEmpty()) {
				log.debug(CATALINA_BASE + " found as property, trying to use it as absolute path");
				String toWebContTmpDir = catalinaBaseDir+File.separator+"tmp";
				File webContTmp = new File(toWebContTmpDir);
				if(webContTmp.exists() && webContTmp.isDirectory()) {
					absolutePath = catalinaBaseDir;
					log.debug("The folder "+toWebContTmpDir+" exists");
				}else {
					log.debug("The folder "+toWebContTmpDir+" does not exist");
				}
			}
		}catch (Exception e) {
			log.warn("I'm not able to use the property: "+CATALINA_BASE);
		}
		*/
		
		if(absolutePath==null) {
			log.debug("Reading the system tmp dir by property: "+JAVA_IO_TMPDIR);
	        // This is the property name for accessing OS temporary directory
	        // or folder.
	        String property = JAVA_IO_TMPDIR;
	        // Get the temporary directory and print it.
	        String tempDir = System.getProperty(property);
	        log.debug("OS current temporary directory is: " + tempDir + ", using it as absolute path");
	        absolutePath = tempDir;
		}
		
		absolutePath = absolutePath.endsWith(File.separator)?absolutePath:absolutePath+File.separator;
		sysGisViewerPathDir = absolutePath+SYSTEM_DIR_NAME_TO_GIS_VIEWER_CONFIG;
		log.info("I'm using the folder system: " + sysGisViewerPathDir + ", to copy/read the config files for exporting WFS data");
		
	}

	
	/**
	 * Instantiates a new WFS exporter system dir.
	 */
	public WFSExporterSystemDir() {
	}
	
	
	/**
	 * Gets the CSV file config.
	 *
	 * @param wfsTo the wfs to
	 * @return the CSV file config
	 * @throws FileNotFoundException the file not found exception
	 */
	public CSVReader getCSVFileConfig(WFS_TO wfsTo) throws FileNotFoundException {
		
		InputStream in = null;
		String fileName = null;
		switch (wfsTo) {
		case EXPORT: {
			in = (InputStream) WFSExporter.class.getResourceAsStream(WFS_DATA_EXPORT_CONFIG_FILE);
			fileName = WFS_DATA_EXPORT_CONFIG_FILE;
			break;
			}
		case VIEW: 
		default: {
			in = (InputStream) WFSExporter.class.getResourceAsStream(WFS_DATA_VIEW_CONFIG_FILE);
			fileName = WFS_DATA_VIEW_CONFIG_FILE;
			}
		}

		File theWFSTConfigFile = null;
		String filePathName = null;
		try {
			filePathName = String.format("%s%s%s", sysGisViewerPathDir,File.separator,fileName);
		    File file = new File(filePathName);
		    if(file.exists()) {
		    	log.info("The WFS config file "+filePathName+" already exists, using it");
		    	theWFSTConfigFile = file;
		    }else {
		    	Path theSystemDir = null;
		    	File dirFile = new File(sysGisViewerPathDir);
		    	if(dirFile.exists() && dirFile.isDirectory()) {
		    		log.debug("The system dir: "+sysGisViewerPathDir+", already exists, using it");
		    		theSystemDir = Paths.get(sysGisViewerPathDir);
		    	}else {
		    		log.debug("The system dir: "+sysGisViewerPathDir+", does not exist, creating it");
		    		theSystemDir = Files.createDirectory(Paths.get(sysGisViewerPathDir));
		    	}
		    	log.debug("The WSF config dir is: "+theSystemDir);
		    	log.info("Copying WFS config file to: "+filePathName);
		    	theWFSTConfigFile = FileUtil.copyInputStreamToFile(in, filePathName);
		    }
		}catch (Exception e) {
			log.info("Error when copying WFS config file to: "+filePathName, e);
			theWFSTConfigFile = fallbackUseTempFile(fileName);
		}
		
		return new CSVReader(theWFSTConfigFile);
	}
	
	
	/**
	 * Fallback use temp file.
	 *
	 * @param fileName the file name
	 * @return the file
	 */
	public static File fallbackUseTempFile(String fileName){
		try {
			log.info("Running fallback by creating WFS config as temp file...");
			InputStream in = (InputStream) WFSExporter.class.getResourceAsStream(fileName);
			return FileUtil.inputStreamToTempFile(in, fileName);
		}catch (Exception e) {
			log.error("Error on reading config for fileName: "+fileName, e);
			return null;
		}
	}
}
