package com.eactive.eai.rms.onl.common.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Stack;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import io.vavr.collection.Set;

public class FileWriteUtil {
	public static String LAYOUT    	= "layout";
	public static String TRANSFORM 	= "transform";
	public static String INTERFACE 	= "interface";
	public static String BAP_CM_DIR = "fileinfo";
	public static String MESSAGEKEY = "messageKey";
	public static String ADMIN     	= "admin";
	public static String ADAPTER   	= "adapter";
	public static String B2B       	= "b2b";
	public static String B2B_EXT	= "b2bext";
	public static String C2R       	= "c2r";
	public static String EXT_TXT   	= ".txt";
	
	public static final Logger logger = Logger.getLogger(FileWriteUtil.class);

	public static void FileWrite(String path, String fileName,LinkedHashMap<String,List> tables)throws Exception{
		String s = StringWrite(tables);
		makeDir(path);
//		File directory = new File(path);
//		directory.setWritable(true,false);
//		directory.setReadable(true,false);
//		directory.setExecutable(true,true);
//		if (!directory.exists()){
//			if (!directory.mkdirs()){
//				throw new Exception("디렉토리 생성 오류입니다."+path);
//			}
//		}
		
		File file = new File(path+fileName);
		if (file.exists()){
			file.delete();
		}
		FileOutputStream os = null;
		BufferedOutputStream bos = null;
		try {
			os = new FileOutputStream(file);
			bos = new BufferedOutputStream(os); 
			bos.write(s.getBytes());
			bos.flush();
			file.setWritable(true,false);
			file.setReadable(true,false);
			file.setExecutable(true,true);
			if (logger.isDebugEnabled()){
				logger.debug(s);
			}
		}
		catch(Exception ex) {
			logger.error("file error", ex);;
		}
		finally {
			try { if(bos != null) bos.close(); } catch(Exception e) {}
			try { if(os != null) os.close(); } catch(Exception e) {}
		}
	}
	public static String StringWrite(LinkedHashMap<String,List> tables)throws Exception{
		String sep =";";
		String newLine ="\n";
		StringBuffer sb = new StringBuffer();
		for (String key : tables.keySet()){
        
			List<LinkedHashMap> table = tables.get(key);
			//make header
	        if (table.size() > 0 ){
	        	 sb.append(key).append(newLine);
	        	 LinkedHashMap<String,Object> header = table.get(0);
	        	 for (String headerStr : header.keySet() ){
	        		 sb.append(headerStr).append(sep);
	             }
	        	 sb.append(newLine);
	        }
	        for( LinkedHashMap<String,Object> row : table ) {
	        	for (String col : row.keySet()){
	                Object obj = row.get(col);
	                String val="";
	                if( obj instanceof Integer ) {
	                    val = "" + (Integer)obj;
	                } else if( obj instanceof BigDecimal ) {
	                	val = ((BigDecimal)obj).toString();
	                } else if( obj instanceof String ) {
	                    val = (String)obj;
	                } else {
	                    val ="";
	                }

	                if(StringUtils.equalsIgnoreCase(col, "DBSQL")) {
	                	sb.append("\n<DBSQL>").append(val).append("</DBSQL>\n").append(sep);
	                } else {
	                	sb.append(val.replaceAll("\n", "").replaceAll("\r", "")).append(sep);
	                }
	        	}
	        	sb.append(newLine);
	        }
		}
		return sb.toString();
	}
   public static void FileWrite(String path, String fileName, String data, String encoding)throws Exception{
		makeDir(path);
		
		File file = new File(path+fileName);
		FileOutputStream os = null;
		BufferedOutputStream bos = null;
		try {
			os = new FileOutputStream(file);
			bos = new BufferedOutputStream(os); 
         bos.write(data.getBytes(encoding));
			bos.flush();
			file.setWritable(true,false);
			file.setReadable(true,false);
			file.setExecutable(true,true);

			if (logger.isDebugEnabled()){
				logger.debug(data);
			}
		}
		catch(Exception ex) {
			logger.error("file error", ex);
			throw ex;
		}
		finally {
			try { if(bos != null) bos.close(); } catch(Exception e) {}
			try { if(os != null) os.close(); } catch(Exception e) {}
		}

   }
   public static void FileWrite(String path, String fileName, String data)throws Exception{
      FileWrite(path, fileName, data, Charset.defaultCharset().name());
	}
	private static void makeDir(String path) throws Exception{
		File directory = new File(path);
		
		if (directory.exists()){
			return;
		}
		
		Stack<File> stack = new Stack<File>();
		//check
		File p = directory;
		stack.push(p);
		while (true){
			p = p.getParentFile();
			if (p.exists()){
				break;
			}else{
				stack.push(p);
			}
		}
		while(!stack.empty()){
			File s = stack.pop();
			s.mkdir();
			s.setWritable(true,false);
			s.setReadable(true,false);
			s.setExecutable(true,true);
		}
	}
	
	public static void makeDirWithGroupPermission(String path) throws Exception{
		File directory = new File(path);
		
		if (directory.exists()){
			return;
		}
		
		Stack<File> stack = new Stack<File>();
		//check
		File p = directory;
		stack.push(p);
		while (true){
			p = p.getParentFile();
			if (p.exists()){
				break;
			}else{
				stack.push(p);
			}
		}
		while(!stack.empty()){
			File s = stack.pop();
			s.mkdir();
			String os = System.getProperty("os.name").toLowerCase();
			// 윈도우면 그냥 리턴
			if (os.contains("win")) {
				return;
			}
			java.util.Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxrwxr-x");
			Files.setPosixFilePermissions(s.toPath(), perms);
		}
	}

}
