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

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.ServiceLocator;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;

public class SqlUtil {

	static Connection conn = null;
	static Statement stmt = null;
	
	private static final Logger logger = Logger.getLogger("runSql.jsp");
	static private String   NEW_LINE  = "\n";
	static private int MAX_FETCH_SIZE = 1000;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static HashMap<String,String> runSql(List<String> list, String serviceType ) throws Exception {

		StringBuffer sb = new StringBuffer();
		StringBuffer errorBuff = new StringBuffer();
		ResultSet rs = null;
		
		try	{
			DataSourceType dataType = DataSourceTypeManager.getDataSourceType(serviceType);
			
			String jndiName = "";
			if(dataType != null){ //취약점소스 수정 2020.08.24
				jndiName = dataType.getJndiName();
			}
			
			ServiceLocator sl = ServiceLocator.getInstance();
			DataSource ds = sl.getDataSource( jndiName);
			
			if(ds != null){ //취약점 소스 수정
				conn = ds.getConnection();
			 }
			stmt = conn.createStatement();
	  		
	  		for(String sql : list) {
		  		try{
		  			
		  			sql = sql.trim();
		  			if(sql.length() == 0) continue;
//	 	  			System.out.println(sql);
		  			if(sql.toUpperCase().startsWith("SELECT")){
		  					// 메모리 문제로 조회건수를 1000건으로 제한하도록 한다. // 요건에 따라 변경 필요
		  					sql = sql + "\n fetch first "+MAX_FETCH_SIZE+" rows only"; // DB2
		  					stmt.execute(sql);
		  					
		  					 if(stmt != null) { //취약점소스 수정
		  						 rs = stmt.getResultSet();
		  					 }
							
	  						if (rs != null) {
	  							List ret = new ArrayList();
	  							int maxColumn = rs.getMetaData().getColumnCount();
	  							ResultSetMetaData rsmd = rs.getMetaData();
	  							String[] colName = new String[maxColumn];
	  							int[] colSize = new int[maxColumn];
	  							//get Col Name
	  							for(int i =1; i<=maxColumn; i++){
	  								colName[i-1] = rsmd.getColumnName(i);
	  								colSize[i-1] = rsmd.getPrecision(i);
	  							}
	  							ret.add(colSize);
	  							ret.add(colName);
	  							if(rs != null){ //취약점 소스 수정
	  								while(rs.next()) {
		  								String[] row = new String[maxColumn];
		  								for (int i=0;i<maxColumn;i++){
		  									row[i] = rs.getString(i+1);
		  								}    	
		  								ret.add(row);
		  							}
	  							}
	  							
	  							sb = ListToString(ret);
	  						}
		  			} else{	//INSERT, UPDATE, DELETE
		  				int affected =	stmt.executeUpdate(sql);
						sb.append("==> Execute - ["+sql.trim()+"], affected "+ affected +" rows").append(NEW_LINE);
		  			}
		
		  		}catch(Exception e){
		  			errorBuff.append("==> Error   - ["+sql + "] / error message : " +e.getMessage()+" / exception : "+e).append(NEW_LINE);
		  		}
			}
		}catch(Exception e) {
			logger.error(e.getMessage(),e);
			throw e;
		}
		finally {
			if(rs != null) try { rs.close(); } catch(SQLException sqle) {logger.error("SQLException was thrown: " + sqle.getMessage());}
			if(stmt != null) try { stmt.close(); } catch(SQLException sqle) {logger.error("SQLException was thrown: " + sqle.getMessage());}
			if(conn != null) try { conn.close(); } catch(SQLException sqle) {logger.error("SQLException was thrown: " + sqle.getMessage());}
			
		}
		
		HashMap retMap = new HashMap();
		retMap.put("result", sb.toString());
		retMap.put("error", errorBuff.toString());
		
		return retMap;
	}

	public static HashMap<String,String> executeSql(String statements,String serviceType) throws Exception {
		
	    String[] arr = statements.split(";");
	    List<String> list = Arrays.asList(arr);
	    	
		return runSql(list, serviceType);
	}
	
	public static StringBuffer ListToString(List<String[]> list){
		StringBuffer sb = new StringBuffer();
		//first item is ColName
		boolean isHead = true;
		for(int row=1;row<list.size();row++){
			String[] ar = (String[])list.get(row);
			for(int i =0; i < ar.length; i++){
				sb.append(ar[i]).append("\t");
			}
			sb.append(NEW_LINE);
			if(isHead){
				sb.append(StringUtils.repeat("--",sb.length())).append(NEW_LINE);
				isHead= false;
			}
		}
		return sb;
	}
}
