package com.eactive.eai.rms.bap.manage.work.inst;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.util.HtmlUtils;

import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.rms.bap.common.base.BapBaseService;
import com.eactive.eai.rms.bap.manage.comm.property.BapPropertyDao;
import com.eactive.eai.rms.bap.manage.comm.property.BapTelePropertyDao;
import com.eactive.eai.rms.common.util.SqlUtil;

@Service("bapSystemInstService")
public class BapSystemInstService extends BapBaseService {

	@Autowired
	@Qualifier("bapSystemInstDao")
	private BapSystemInstDao dao;

	@Autowired
	@Qualifier("bapTelePropertyDao")
	private BapTelePropertyDao telePropDao;

	@Autowired
	@Qualifier("bapPropertyDao")
	private BapPropertyDao propDao;

	public HashMap<String, Object> selectList(int startNum,int endNum, HashMap<String, Object> paramMap) throws Exception {

      // 전체 목록수 얻기
      int totalCount = dao.selectListCount(paramMap);

      paramMap.put("startNum" , startNum);// 시작 record
      paramMap.put("endNum"   , endNum);// 끝 record

      List<Map<String, Object>> list = dao.selectList(paramMap);
      HashMap<String, Object> map = new HashMap<String, Object>();

		map.put("totalCount", totalCount);
		map.put("list", list);

		return map;
	}	

	public HashMap<String, Object> selectDetail(HashMap<String, Object> param) throws Exception {

		String bjobBzwkDstcd = (String)param.get("bjobBzwkDstcd");
		String osidInstiDstcd = (String)param.get("osidInstiDstcd");
		param.put("prptyGroupName", "TelegramInfo{" + bjobBzwkDstcd + "_" + osidInstiDstcd + "}");
      HashMap<String, Object>   detail        = dao.selectDetail(param);
		List<Map<String, Object>> list          = dao.getProps(param);
		List<Map<String, Object>> sysConnList   = dao.selectDetailSysconn(param);
		HashMap<String, Object> map = new HashMap<String, Object>();

//      System.out.println( "list-->" + list.size());
		logger.debug( "list-->" + list.size());
		map.put("detail", detail);
		map.put("rows", list);
		map.put("sysConnList", sysConnList);

		return map;

	}

	public void update(HashMap<String, Object> paramMap, HashMap<String, Object>[] list, HashMap<String, Object> connList) throws Exception {
		boolean hasProp = false;
		dao.update(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
		HashMap<String, Object> prop ;
		for(HashMap<String, Object> map : list){
			String prptyName = (String)map.get("PRPTYNAME");
			String prpty2Val = (String)map.get("PRPTY2VAL");
			if ( !prptyName.equals("") && !prpty2Val.equals("")){
				prop = new HashMap<String, Object>();
				prop.putAll(paramMap);
				prop.put("prptyGroupName",paramMap.get("prptyGroupName"));
				prop.put("prptyName", prptyName);
				prop.put("prpty2Val", prpty2Val);
				telePropDao.insertProperty(prop);
				hasProp = true;
			}
		}
		if ( hasProp ) telePropDao.insert(paramMap);
		
		dao.deleteSysconn(paramMap);
        for (String key : connList.keySet()) {
        	//String key = (String)obj;
        	HashMap<String, Object> data = new HashMap<String, Object>();
        	@SuppressWarnings("unchecked")
			HashMap<String, Object> connMap = convertToHashMap((com.google.gson.internal.LinkedTreeMap<String, Object>)connList.get(key));
        	
        	String lnkgId =  StringUtil.getNullStr(connMap.get("LNKGID"));
        	String lnkgPwd = StringUtil.getNullStr(connMap.get("LNKGPWD"));
        	     	
			data.put("bjobBzwkDstcd"     , paramMap.get("bjobBzwkDstcd"));
			data.put("osidInstiDstcd"    , paramMap.get("osidInstiDstcd"));
			data.put("sysLnkgDstcd"      , connMap.get("SYSLNKGDSTCD"      ));
			data.put("rqstRspnsDstcd"    , connMap.get("RQSTRSPNSDSTCD"    ));
			data.put("lnkgIPInfoName"    , connMap.get("LNKGIPINFONAME"    ));
			data.put("lnkgPortInfoName"  , connMap.get("LNKGPORTINFONAME"  ));
			data.put("lnkgID"            , HtmlUtils.htmlUnescape(lnkgId));
			data.put("lnkgPwd"           , HtmlUtils.htmlUnescape(lnkgPwd));
			data.put("toutVal"           , "60");
			data.put("tcirtLnkgStusCd"   , connMap.get("TCIRTLNKGSTUSCD"   ));
			data.put("adptrBzwkGroupName", StringUtil.getNullStr( connMap.get("ADPTRBZWKGROUPNAME")));
			data.put("adptrBzwkName"     , StringUtil.getNullStr(connMap.get("ADPTRBZWKNAME"     )));
			data.put("sysGbName"         , StringUtil.getNullStr(connMap.get("SYSGBNAME"     )));
			data.put("thisMsgUseYn"      , connMap.get("THISMSGUSEYN"      ));
			//data.put("thisMsgRegsntID"   , connMap.get("THISMSGREGSNTID"   ));
			data.put("thisMsgRegiHMS"    , connMap.get("THISMSGREGIHMS"    ));
			//data.put("thisMsgAmndrID"    , paramMap.get("thisMsgAmndrID"    ));
			//data.put("thisMsgAmndHMS"    , connMap.get("THISMSGAMNDHMS"    ));
			data.put("userid"             , paramMap.get("userid"));
			data.put("RMARKITEMCTNT"             , paramMap.get("RMARKITEMCTNT"));
			data.put("CIRNUMBER"             , paramMap.get("CIRNUMBER"));
    		dao.insertSysconn(data);
        }

	}

	public void insert(HashMap<String, Object> paramMap, HashMap<String, Object>[] list, HashMap<String, Object> connList) throws Exception {
		boolean hasProp = false;
		dao.insert(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
		HashMap<String, Object> prop ;
		for(HashMap<String, Object> map : list){
			String prptyName = (String)map.get("PRPTYNAME");
			String prpty2Val = (String)map.get("PRPTY2VAL");
			if ( !prptyName.equals("") && !prpty2Val.equals("")){
				prop = new HashMap<String, Object>();
				prop.putAll(paramMap);
				prop.put("prptyGroupName",paramMap.get("prptyGroupName"));
				prop.put("prptyName", prptyName);
				prop.put("prpty2Val", prpty2Val);
				telePropDao.insertProperty(prop);
				hasProp = true;
			}
		}
		if ( hasProp ) telePropDao.insert(paramMap);
		
		dao.deleteSysconn(paramMap);
        for (String key : connList.keySet()) {
        	//String key = (String)obj;
        	HashMap<String, Object> data = new HashMap<String, Object>();
        	@SuppressWarnings("unchecked")
			HashMap<String, Object> connMap = convertToHashMap((com.google.gson.internal.LinkedTreeMap<String, Object>)connList.get(key));
        	
        	String lnkgId =  StringUtil.getNullStr(connMap.get("LNKGID"));
        	String lnkgPwd = StringUtil.getNullStr(connMap.get("LNKGPWD"));
        	
			data.put("bjobBzwkDstcd"     , paramMap.get("bjobBzwkDstcd"));
			data.put("osidInstiDstcd"    , paramMap.get("osidInstiDstcd"));
			data.put("sysLnkgDstcd"      , connMap.get("SYSLNKGDSTCD"      ));
			data.put("rqstRspnsDstcd"    , connMap.get("RQSTRSPNSDSTCD"    ));
			data.put("lnkgIPInfoName"    , connMap.get("LNKGIPINFONAME"    ));
			data.put("lnkgPortInfoName"  , connMap.get("LNKGPORTINFONAME"  ));
			data.put("lnkgID"            , HtmlUtils.htmlUnescape(lnkgId));
			data.put("lnkgPwd"           , HtmlUtils.htmlUnescape(lnkgPwd));
			data.put("toutVal"           , "60");
			data.put("tcirtLnkgStusCd"   , connMap.get("TCIRTLNKGSTUSCD"   ));
			data.put("adptrBzwkGroupName", StringUtil.getNullStr(connMap.get("ADPTRBZWKGROUPNAME")));
			data.put("adptrBzwkName"     , StringUtil.getNullStr(connMap.get("ADPTRBZWKNAME"     )));
			data.put("sysGbName"         , StringUtil.getNullStr(connMap.get("SYSGBNAME"     )));
			data.put("thisMsgUseYn"      , connMap.get("THISMSGUSEYN"      ));
			//data.put("thisMsgRegsntID"   , connMap.get("THISMSGREGSNTID"   ));
			data.put("thisMsgRegiHMS"    , connMap.get("THISMSGREGIHMS"    ));
			//data.put("thisMsgAmndrID"    , paramMap.get("thisMsgAmndrID"    ));
			//data.put("thisMsgAmndHMS"    , connMap.get("THISMSGAMNDHMS"    ));
			data.put("userid"             , paramMap.get("userid"));
			data.put("RMARKITEMCTNT"             , paramMap.get("RMARKITEMCTNT"));
			data.put("CIRNUMBER"             , paramMap.get("CIRNUMBER"));
    		dao.insertSysconn(data);
        }

	}

	public void clone(HashMap<String, Object> paramMap, HashMap<String, Object>[] list) throws Exception {
		dao.insert(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
		if (list.length > 0) telePropDao.insert(paramMap);
		for(HashMap<String, Object> map : list){
			String prptyName = (String)map.get("PRPTYNAME");
			String prpty2Val = (String)map.get("PRPTY2VAL");
			if ( !prptyName.equals("") && !prpty2Val.equals("")){
				HashMap<String, Object> prop = new HashMap<String, Object>();
				prop.putAll(paramMap);
				prop.put("prptyGroupName",paramMap.get("prptyGroupName"));
				prop.put("prptyName", prptyName);
				prop.put("prpty2Val", prpty2Val);
				telePropDao.insertProperty(prop);
			}
		}
	}	
	
	public void delete(HashMap<String, Object> paramMap) throws Exception {
		dao.delete(paramMap);
		dao.deleteSysconn(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
	}	

	public List<Map<String, Object>> getAdaptorGroup() throws Exception {
		 
		return dao.getAdaptorGroup();
	}	

	public List<Map<String, Object>> getAdptrBzwkName( String adptrBzwkGroupName, String rqstRspnsDstcd) throws Exception {
		
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ADPTRBZWKNAME", " ");
		map.put("ADPTRDESC", "없음");
		if ( !rqstRspnsDstcd.equals("R")){
			HashMap<String, Object> paraMap = new HashMap<String, Object>();
			paraMap.put("adptrBzwkGroupName", adptrBzwkGroupName);
			//paraMap.put("rqstRspnsDstcd", rqstRspnsDstcd);
			//list.addAll(c)
			list = dao.getAdaptor( paraMap);
		}
		list.add(map);
		return list;
	}	

	@SuppressWarnings("unchecked")
	public HashMap<String,String> mkInsertSqlForSystemInst(HashMap<String, Object> systemInstDetail) throws Exception {
		
		StringBuffer systemInstInsertSql = new StringBuffer();
		
		HashMap<String, Object>   detail      = (HashMap<String, Object>)systemInstDetail.get("detail");
		List<Map<String, Object>> propList    = (List<Map<String, Object>>)systemInstDetail.get("rows");
		List<Map<String, Object>> sysConnList = (List<Map<String, Object>>)systemInstDetail.get("sysConnList");

		String bjobBzwkDstcd = (String)detail.get("BJOBBZWKDSTCD");
		String osidInstiDstcd = (String)detail.get("OSIDINSTIDSTCD");
		detail.put("PRPTYGROUPNAME", "TelegramInfo{" + bjobBzwkDstcd + "_" + osidInstiDstcd + "}");
		
		String[] columnUserId = {"THISMSGREGSNTID","THISMSGAMNDRID"};  // userID 입력컬럼 구분
		String[] columnDateTime = {"THISMSGREGIHMS","THISMSGAMNDHMS"};  // DateTime 입력컬럼 구분
		String userid = systemInstDetail.get("userid") != null ? systemInstDetail.get("userid").toString() : "";
		
		// 시스템대외기관 into BJ06
		List<String> columnArr = new ArrayList<String>();
		String[] columnList = {"BJOBBZWKDSTCD","OSIDINSTIDSTCD","OSIDINSTINAME","ADPTRBZWKGROUPNAME","SENDPRCSSRULECD","RECVPRCSSRULECD",
							   "EAIFILESENDPTRNDSTCD","EAIFILERECVPTRNDSTCD","TELGMBLCKSIZE","TELGMSERNOSIZE","TELGMPCKETSIZE","TRANSTARTINDX",
							   "TRANENDINDX","THISMSGUSEYN","THISMSGREGSNTID","THISMSGREGIHMS","THISMSGAMNDRID","THISMSGAMNDHMS","SENDPRCSSPTCOLNAME",
							   "RECVPRCSSPTCOLNAME","SENDECRYPWAYNAME","RECVECRYPWAYNAME","SENDDIRNAME","RECVDIRNAME","OSIDINSTIBZWKRSEMPNAME","OSIDINSTITELNO",
							   "SMSDPSTCNSNTYN","RSEMPNAME","RMARKITEMCTNT", "CIRNUMBER"};
		columnArr = Arrays.asList(columnList);
		systemInstInsertSql.append("INSERT INTO EAIPKG.TSEAIBJ06 (");
		
		// 필드명 입력
		for (String column : columnArr) {
			systemInstInsertSql.append((column.equals(columnArr.get(columnArr.size()-1))) ? column : column+",");
		}
		systemInstInsertSql.append(") VALUES (");
		// 필드값 입력
		String[] columnInt = {"TELGMBLCKSIZE","TELGMSERNOSIZE","TELGMPCKETSIZE","TRANSTARTINDX","TRANENDINDX"};  // Integer 컬럼 구분
		for (String column : columnArr) {
			if (column.equals(columnArr.get(columnArr.size()-1))) {
				if (Arrays.asList(columnInt).contains(column)) {
					systemInstInsertSql.append((detail.get(column) != null ? detail.get(column) : 0)+");\n");
				} else {
					if (Arrays.asList(columnUserId).contains(column)) {
						systemInstInsertSql.append("'"+userid+"');\n");
					} else if (Arrays.asList(columnDateTime).contains(column)) {
						systemInstInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'));\n");
					} else {
						systemInstInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"');\n");
					}
				}
			} else {
				if (Arrays.asList(columnInt).contains(column)) {
					systemInstInsertSql.append((detail.get(column) != null ? detail.get(column) : 0)+",");
				} else {
					if (Arrays.asList(columnUserId).contains(column)) {
						systemInstInsertSql.append("'"+userid+"',");
					} else if (Arrays.asList(columnDateTime).contains(column)) {
						systemInstInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
					} else {
						if (column.equals("EAIFILESENDPTRNDSTCD")) column = "FILESENDPTRNDSTCD";
						if (column.equals("EAIFILERECVPTRNDSTCD")) column = "FILERECVPTRNDSTCD";
						systemInstInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"',");
					}
				}
			}
		}

		// 대외기관 연결정보 into BJ05
		for (Map<String, Object> connInfo : sysConnList) {

			List<String> columnConnArr = new ArrayList<String>();
			String[] columnConnList = {"SYSLNKGDSTCD","BJOBBZWKDSTCD","OSIDINSTIDSTCD","RQSTRSPNSDSTCD","LNKGIPINFONAME","LNKGPORTINFONAME","LNKGID",
									    "LNKGID2","TOUTVAL","TCIRTLNKGSTUSCD","ADPTRBZWKGROUPNAME","ADPTRBZWKNAME","THISMSGUSEYN","THISMSGREGSNTID",
									    "THISMSGREGIHMS","THISMSGAMNDRID","THISMSGAMNDHMS","SYSGBNAME"};
			columnConnArr = Arrays.asList(columnConnList);
			systemInstInsertSql.append("INSERT INTO EAIPKG.TSEAIBJ05 (");
			
			// 필드명 입력
			for (String column : columnConnArr) {
				systemInstInsertSql.append((column.equals(columnConnArr.get(columnConnArr.size()-1))) ? column : column+",");
			}
			systemInstInsertSql.append(") VALUES (");
			// 필드값 입력
			String[] columnConnInt = {"TOUTVAL"};  // Integer 컬럼 구분
			for (String column : columnConnArr) {
				if (column.equals(columnConnArr.get(columnConnArr.size()-1))) {
					if (Arrays.asList(columnConnInt).contains(column)) {
						systemInstInsertSql.append((connInfo.get(column) != null ? connInfo.get(column) : 0)+");\n");
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							systemInstInsertSql.append("'"+userid+"');\n");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							systemInstInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'));\n");
						} else {
							systemInstInsertSql.append("'"+(connInfo.get(column) != null ? connInfo.get(column) : "")+"');\n");
						}
					}
				} else {
					if (Arrays.asList(columnConnInt).contains(column)) {
						systemInstInsertSql.append((connInfo.get(column) != null ? connInfo.get(column) : 0)+",");
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							systemInstInsertSql.append("'"+userid+"',");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							systemInstInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
						} else {
							systemInstInsertSql.append("'"+(connInfo.get(column) != null ? connInfo.get(column) : "")+"',");
						}
					}
				}
			}
		}
		
		// TELEGRAM PROP GROUP into BA05 (공통코드에서 별도로 입력됨)
		List<String> columnPropGrpArr = new ArrayList<String>();
		String[] columnPropGrpList = {"PRPTYGROUPNAME","PRPTYGROUPDESC"};
		columnPropGrpArr = Arrays.asList(columnPropGrpList);
		systemInstInsertSql.append("INSERT INTO EAIPKG.TSEAIBA05 (");
		
		// 필드명 입력
		for (String column : columnPropGrpArr) {
			systemInstInsertSql.append((column.equals(columnPropGrpArr.get(columnPropGrpArr.size()-1))) ? column : column+",");
		}
		systemInstInsertSql.append(") VALUES (");
		// 필드값 입력
		for (String column : columnPropGrpArr) {
			if (column.equals(columnPropGrpArr.get(columnPropGrpArr.size()-1))) {
				systemInstInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"');\n");
			} else {
				systemInstInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"',");
			}
		}
		
		// TELEGRAM PROP LIST into BA06 (프로퍼티명과 프로퍼티설명은 업무구분에서 별도로 입력되고, 프로퍼티값만 여기서 업데이트됨)
		for (Map<String, Object> prop : propList) {
			List<String> columnPropArr = new ArrayList<String>();
			String[] columnPropList = {"PRPTYGROUPNAME","PRPTYNAME","PRPTY2VAL"};
			columnPropArr = Arrays.asList(columnPropList);
			systemInstInsertSql.append("INSERT INTO EAIPKG.TSEAIBA06 (");
			
			// 필드명 입력
			for (String column : columnPropArr) {
				systemInstInsertSql.append((column.equals(columnPropArr.get(columnPropArr.size()-1))) ? column : column+",");
			}
			systemInstInsertSql.append(") VALUES (");
			// 필드값 입력
			for (String column : columnPropArr) {
				if (column.equals("PRPTYGROUPNAME")) {
					systemInstInsertSql.append("'"+detail.get("PRPTYGROUPNAME")+"',");
				} else if (column.equals(columnPropArr.get(columnPropArr.size()-1))) {
					systemInstInsertSql.append("'"+(prop.get(column) != null ? prop.get(column) : "")+"');\n");
				} else {
					systemInstInsertSql.append("'"+(prop.get(column) != null ? prop.get(column) : "")+"',");
				}
			}
		}

		HashMap<String,String> retMap = new HashMap<String,String>(); 
		if (systemInstDetail.get("fileName") != null) {
			OutputStream output = null;
			try {
				String sqlDownloadPath = getProperties("SQL_DOWNLOAD", "DOWNLOAD_PATH");
				String sqlDownloadFile = sqlDownloadPath+systemInstDetail.get("fileName");
				output = new FileOutputStream(sqlDownloadFile);
				if (sqlDownloadPath != null) {
					byte[] bt = systemInstInsertSql.toString().getBytes();
					output.write(bt);
					output.close();
				}
				retMap.put("path", sqlDownloadPath);
			} catch (Exception e) {
				logger.error( e.getMessage(), e);
			} finally {
				if(output != null) try { output.close(); } catch(Exception ee) {logger.error( ee.getMessage(), ee);}
			}
		} else {
			retMap = SqlUtil.executeSql(systemInstInsertSql.toString(), "BAP_"+systemInstDetail.get("svrType").toString().toUpperCase());
		}
		
		return retMap;
	}
	
	public HashMap<String, Object> getProps(String bjobBzwkDstcd, String prptyGroupName) throws Exception {

		HashMap<String, Object> param = new HashMap<String, Object>();
		param.put("bjobBzwkDstcd", bjobBzwkDstcd);
		param.put("prptyGroupName", prptyGroupName);

		List<Map<String, Object>> list = dao.getProps(param);
		HashMap<String, Object> map = new HashMap<String, Object>();

		map.put("rows", list);

		return map;

	}
	
	private String getProperties(String propGroup, String propName) throws Exception {
		HashMap<String,Object> params = new HashMap<String,Object>();
		params.put("prptyGroupName", propGroup);
		params.put("prptyName", propName);
		
		HashMap<String, Object> props = propDao.getProperties(params);
		
		return props.get("PRPTY2VAL").toString();
	}
	
	private HashMap<String, Object> convertToHashMap(com.google.gson.internal.LinkedTreeMap<String, Object> linkedTreeMap){
		HashMap<String, Object> h = new HashMap<String, Object>();
		for(Object obj : linkedTreeMap.keySet()){
			String key = (String)obj;
			h.put(key, linkedTreeMap.get(key));
		}
		return h;
	}

}