package com.eactive.eai.batch.flowController;

import com.eactive.eai.common.dao.BaseDAO;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.exception.ExceptionUtil;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;

/**
* 1. 기능 : EAI서버 정보 테이블에 대한 Data Access Object 이다.
* 2. 처리 개요 :  EAI서버 정보 테이블에 대한 Create, Read, Update, Delete 를 처리한다.
*
* 3. 주의사항
*
*/
public class FlowControllerDAO extends BaseDAO implements FlowControllerQuery
{

    /**
    * 1. 기능 : 업무별 기본 정보 전체를 메모리에 로딩하기 위해 테이블 전체 내용을 SELECT해서
    *       BatchTargetVO 객체 리스트로 생성 반환하는 메서드.
    * 2. 처리 개요 : TSEAIBJ02 테이블을 조회해서 각 업무 기본 정보를 가져오고, 해당 업무별 연결 정보를
    *       TSEAIBJ05 테이블에서 조회하여 연결 정보들을 DemandTargetVO[]로 만든 다음, processCode를 key로 하여
    *       전체를 hashmap의 형태로 반환한다.
    * 3. 주의사항
    *
    * @return   Flow Rule 정보 전체데이터로 FlowRuleVO Collection
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 EAI서버 정보를 가져오다 발생되는 모든 에러
    **/
    public HashMap<String, BatchTargetVO> getAllTargets() throws DAOException
    {
		ResultSet rs = null;

		try {

			this.connect(GET_ALL_TARGETS);
			//logger.debug("FlowControllerDAO.getAllTargets() >>> 수행 SQL 문 : \n"+ GET_ALL_TARGETS);

			rs = executeQuery();

			HashMap<String, BatchTargetVO> all = new HashMap<String, BatchTargetVO>();

        while (rs.next()) {
            BatchTargetVO vo = new BatchTargetVO(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
            logger.debug("  - 대외기관 정보 로딩됨 ("+ vo.getProcessCode() +": "+ vo.getProcessName() +", "+ vo.getOrganCode() +": "+ vo.getOrganName() +")");

            vo.setDemadnTargets(this.getDemandTartgetArray(vo.getProcessCode(), vo.getOrganCode()));
            all.put(vo.getProcessCode() + vo.getOrganCode(), vo);
        }

			return all;


		} catch (DAOException ex) {
			throw ex;
		} catch (Exception ex) {
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIMFC001");
			throw new DAOException(errMsg);   //요구송신 전체 대외기관 연결정보 로딩시 오류가 발생하였습니다.
        } finally {
            this.disconnect();
        }
    }

	private DemandTargetVO[] getDemandTartgetArray(String processCode, String organCode) throws DAOException {

		ResultSet rs = null;
		int index = 0;

		try {

			super.preparedStatement = conn.prepareStatement(GET_DETAIL_DEMAND_TARGETS);
			//logger.debug("FlowControllerDAO.getDemandTartgetArray() >>> 수행 SQL 문 : \n"+ GET_DETAIL_DEMAND_TARGETS);

			index = 1;
			this.preparedStatement.setString(index++, processCode);	//logger.debug("FlowControllerDAO.getDemandTartgetArray() >>> 바인드("+(index-1)+") : ["+ processCode     +"]");
			this.preparedStatement.setString(index++, organCode  );	//logger.debug("FlowControllerDAO.getDemandTartgetArray() >>> 바인드("+(index-1)+") : ["+ organCode       +"]");

			rs = executeQuery();

			ArrayList<DemandTargetVO> aList = new ArrayList<DemandTargetVO>();
			while (rs.next()) {
				DemandTargetVO vo = new DemandTargetVO(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getString(5),rs.getString(6),rs.getString(7));
				logger.debug("    > 대외기관 요구송수신 연결 정보 ☞ (IP: "+ vo.getIpAddress() +", Port: "+ vo.getPortNumber() +", ID: "+ vo.getSocketID() +", PW: "+ vo.getSocketPwd() +", Timeout: "+ vo.getTimeoutInterval() +", OrganStatus: "+ vo.getOrganSocketStatus() +")");
				aList.add(vo);
			}

			//logger.debug("FlowControllerDAO.getDemandTartgetArray() >>> 요구송수신 시스템 연결정보 건수: "+ aList.size());
			if (aList.size() == 0) {
				logger.debug("    > 대외기관 요구송수신 연결 정보 없음");
				return new DemandTargetVO[0];
			}

			DemandTargetVO[] demandTargetArray = new DemandTargetVO[aList.size()];
			aList.toArray(demandTargetArray);

			return demandTargetArray;


		} catch (DAOException ex) {
			throw ex;
		} catch (Exception ex) {
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIMFC002", new String[] {processCode, organCode});
			throw new DAOException(errMsg);   //요구송신 업무구분(%1) 대외기관(%2)에 해당하는 연결정보 로딩시 오류가 발생하였습니다.
		} finally {
			//ResultSet 과 PreparedStatement 만 close. Connection 은 Close 하면 안됨
			try { if (rs!=null) rs.close(); } catch (Exception e) {throw new DAOException("BECEAICDB106");}
			super.closeStatement();
		}
	}

	public BatchTargetVO getBatchTargetVO(String processCode, String organCode) throws DAOException {

		ResultSet rs = null;
		int index = 0;

		try {

			this.connect(GET_BATCH_TARGETS);
			//logger.debug("FlowControllerDAO.getBatchTargetVO() >>> 수행 SQL 문 : \n"+ GET_BATCH_TARGETS);

			index = 1;
			this.preparedStatement.setString(index++, processCode);	//logger.debug("FlowControllerDAO.getBatchTargetVO() >>> 바인드("+(index-1)+") : ["+ processCode     +"]");
			this.preparedStatement.setString(index++, organCode  );	//logger.debug("FlowControllerDAO.getBatchTargetVO() >>> 바인드("+(index-1)+") : ["+ organCode       +"]");

			rs = executeQuery();

			if (rs.next() == false) {
				//logger.debug("ResponseFlowDAO.getBatchTargetVO() >>> 요구송수신 시스템정보 건수: 0");
				String errMsg = ExceptionUtil.getErrorCode("BECEAIMFC003", new String[] {processCode, organCode});
				throw new DAOException(errMsg);	//업무구분(%1)의 대외기관(%2) 정보가 등록되지 않았습니다.
			}

			//logger.debug("ResponseFlowDAO.getBatchTargetVO() >>> 요구송수신 시스템정보 건수: 1");
			BatchTargetVO vo = new BatchTargetVO(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
			logger.debug("  - 대외기관 정보 로딩됨 ("+ vo.getProcessCode() +": "+ vo.getProcessName() +", "+ vo.getOrganCode() +": "+ vo.getOrganName() +")");
            vo.setDemadnTargets(this.getDemandTartgetArray(vo.getProcessCode(), vo.getOrganCode()));
			return vo;


		} catch (DAOException ex) {
			throw ex;
		} catch (Exception ex) {
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIMFC002", new String[] {processCode, organCode});
			throw new DAOException(errMsg);	//요구송신 업무구분(%1) 대외기관(%2)에 해당하는 연결정보 로딩시 오류가 발생하였습니다.
		} finally {
			disconnect();
		}
	}





    /**
    * 1. 기능 : 전달된 UUID에 해당하는 MsgPrcssStusCd 정보를 반환한다.
    * 2. 처리 개요 : 전달된 UUID에 해당하는 MsgPrcssStusCd 정보를 읽어온다.
    * 3. 주의사항
    *
    * @return
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 전문 정보를 가져오다 발생되는 모든 에러
    **/
    public String getStatusCode(String uuid) throws DAOException
    {
        try
        {
            ResultSet rs = null;
            String statusCode = "";

            // 연결정보의 전체 갯수를 읽어온다.
            this.connect(GET_STATUS_CODE);
            this.preparedStatement.setString(1, uuid);
            rs = this.executeQuery();

            if(rs.next()) {
                statusCode = rs.getString(1);
            } else {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIMFC008", new String[] {uuid});
				throw new DAOException(errMsg);	//작업진행 테이블에 해당 정보가 없습니다. (UUID: %1)
            }
            rs.close();

            return statusCode;
        } catch(Exception e) {
			String errMsg = ExceptionUtil.getErrorCode(e, "BECEAIMFC009", new String[] {uuid});
			throw new DAOException(errMsg);	//작업진행 테이블에서 해당 작업의 상태 정보 조회시 오류가 발생하였습니다. (UUID: %1)
        } finally {
            this.disconnect();
        }
    }


	public int updateSystemConnLineStatus(String processCode, String organCode, String lineStatus) throws DAOException {

		int       retValue = 0;
		int       index    = 0;

		try {

			this.connect(UPDATE_SYSTEM_CONN_LINE_STATUS);
			//logger.debug("FlowControllerDAO.updateSystemConnLineStatus() >>> 수행 SQL 문 : \n"+ ResponseFlowQuery.UPDATE_SYSTEM_CONN_LINE_STATUS);

			index = 1;
			this.preparedStatement.setString(index++, lineStatus );	//logger.debug("ResponseFlowDAO.updateSystemConnLineStatus() >>> 바인드("+(index-1)+") : ["+ lineStatus    +"]");
			this.preparedStatement.setString(index++, processCode);	//logger.debug("ResponseFlowDAO.updateSystemConnLineStatus() >>> 바인드("+(index-1)+") : ["+ processCode   +"]");
			this.preparedStatement.setString(index++, organCode  );	//logger.debug("ResponseFlowDAO.updateSystemConnLineStatus() >>> 바인드("+(index-1)+") : ["+ organCode     +"]");

			retValue = this.executeUpdate();
			logger.debug("FlowControllerDAO.updateSystemConnLineStatus() >>> 연결 회선 상태 UPDATE 건 수 : "+ retValue);

			if (retValue == 0) {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIFRF010", new String[] {lineStatus});
				throw new DAOException(errMsg);  //대외기관 연결정보 테이블에 회선 상태 update 건수가 0 건입니다. (회선상태: {1})
			}

		} catch (DAOException ex) {
			throw ex;
		} catch (Exception ex) {
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIFRF011", new String[] {lineStatus});
			throw new DAOException(errMsg);  //대외기관 연결정보 테이블에 회선 상태 update 시 오류가 발생하였습니다.(회선상태: {1})
		} finally {
			disconnect();
		}
		return retValue;
	}


}
