package com.eactive.eai.batch.telegram;

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.HashMap;

/**
* 1. 기능 : 전문 정보 테이블에 대한 Data Access Object 이다.
* 2. 처리 개요 :  전문 정보 테이블에 대한 Create, Read, Update, Delete 를 처리한다.
*
* 3. 주의사항
*
* @author  :
* @version : v 1.0.0
* @see :
* @since   :
*/
public class TelegramDAO extends BaseDAO implements TelegramQuery
{

    /**
    * 1. 기능 : 특정 전문 Key에 해당하는 객체를 DB에서 로딩하여 HashMap에 추가한다.
    * 2. 처리 개요 : 특정 전문 정보를 SELECT해서 하나의 TelegramVO의 배열을 만들어서 저장한다.
    *
    * 3. 주의사항
    *
    * @return
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 EAI서버 정보를 가져오다 발생되는 모든 에러
    **/
    public TelegramVO getTelegram(String telegramKey) throws DAOException
    {
        ResultSet rs = null;
        TelegramVO telegramVO = new TelegramVO();

        try
        {
            // 해당 전문의 필드의 갯수를 읽어온다.
            int totalFieldCnt = this.getTelegramFieldCount(telegramKey);

            // 해당 전문의 내용을 읽어온다.
            this.connect(GET_TELEGRAM_INFO);
            this.preparedStatement.setString(1, telegramKey);
            rs = this.executeQuery();

            telegramVO = new TelegramVO(telegramKey, totalFieldCnt);

            while(rs.next())
            {
                // telegramitem 순서값은 런타임시에는 사용하지 않는다. 대신 TelegramVO에서 item이 추가될때 순서를 부여한다.
                // 이러한 이유는 TSEAIBM02에서 수정작업을 편하게 하도록 하기 위함이다.
                TelegramItemVO itemVO = new TelegramItemVO(rs.getString(3).trim(), rs.getString(4).trim(), rs.getString(5).trim(), rs.getString(6).trim());

                // 전문 필드중에 가변부가 있으면 전문의 variableFieldCheckTag를 true로 세팅한다.
                if (rs.getString(5).trim().toUpperCase().equals("XX"))
                {
                    telegramVO.setVariableFieldCheckTag(true);
                }
                telegramVO.addTelegramItem(itemVO);

            }
            //all.put(telegramVO.getTelegramKey(), telegramVO);

        } catch(Exception e) {
			String errMsg = ExceptionUtil.getErrorCode(e, "BECEAIMTM001", new String[] {telegramKey});
			throw new DAOException(errMsg);	//전문Key (%1)에 해당하는 전문필드 정보 조회시 오류가 발생하였습니다.
        } finally {
            this.disconnect();
        }
        return telegramVO;
    }


    /**
    * 1. 기능 : 전문 정보 전체를 메모리에 로딩하기 위해 테이블 전체 내용을 SELECT해서
    *           TelegramVO 객체 리스트로 생성 반환하는 메서드.
    * 2. 처리 개요 : 전문 정보 전체를 SELECT해서 하나의 TelegramVO의 배열을 만들어서 저장한다.
    *
    * 3. 주의사항
    *
    * @return
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 EAI서버 정보를 가져오다 발생되는 모든 에러
    **/
    public HashMap<String, TelegramVO> getAllTelegrams() throws DAOException
    {
        HashMap<String, TelegramVO> all = new HashMap<String, TelegramVO>();
        ResultSet rs = null;
        try
        {
            // 전문의 전체 갯수를 읽어온다.
            int totalKeyCnt = this.getTelegramKeyCount();

            // 전문의 Key를 읽어온다.
            String[] keys = new String[totalKeyCnt];
            String[] fieldsCount = new String[totalKeyCnt];
            this.connect(GET_TELEGRAM_KEYS);
            rs = this.executeQuery();
            int k=0;
            while(rs.next())
            {
                keys[k] = rs.getString(1);
                fieldsCount[k] = rs.getString(2);
                k++;
            }
            rs.close();

            // 전문 Key별로 해당 필드들의 내용을 읽어온다.
            for(int i=0; i<keys.length; i++)
            {
                this.prepareStatement(GET_TELEGRAM_INFO);
                this.preparedStatement.setString(1, keys[i]);

                rs = this.executeQuery();

                TelegramVO telegramVO = new TelegramVO(keys[i], new Integer(fieldsCount[i]).intValue());
                while(rs.next())
                {
                    // telegramitem 순서값은 런타임시에는 사용하지 않는다. 대신 TelegramVO에서 item이 추가될때 순서를 부여한다.
                    // 이러한 이유는 TSEAIBM02에서 수정작업을 편하게 하도록 하기 위함이다.
                    TelegramItemVO itemVO = new TelegramItemVO(rs.getString(3).trim(), rs.getString(4).trim(), rs.getString(5).trim(), rs.getString(6).trim());

                    // 전문 필드중에 가변부가 있으면 전문의 variableFieldCheckTag를 true로 세팅한다.
                    if (rs.getString(5).trim().toUpperCase().equals("XX"))
                    {
                        telegramVO.setVariableFieldCheckTag(true);
                    }
                    telegramVO.addTelegramItem(itemVO);
                }
                all.put(telegramVO.getTelegramKey(), telegramVO);
				logger.debug("  - '"+ keys[i] +"' 전문 로딩됨 (Field Count: "+ fieldsCount[i] +")");
            }
        } catch(Exception e) {
			String errMsg = ExceptionUtil.getErrorCode(e, "BECEAIMTM002");
			throw new DAOException(errMsg);	//전체 전문 정보 조회시 오류가 발생하였습니다.
        } finally {
            this.disconnect();
        }
        return all;
    }

    /**
    * 1. 기능 : TSEAIBM02에 저장된 전문의 Key만을 반환한다.
    * 2. 처리 개요 : 등록된 전문이 없는 경우 0, 그외 전문의 갯수를 반환한다.
    *
    * 3. 주의사항
    *
    * @return
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 전문 정보를 가져오다 발생되는 모든 에러
    **/
    public int getTelegramKeyCount() throws DAOException
    {
        try
        {
            ResultSet rs = null;
            int totalKeyCnt = 0;   // Key의 count를 반환하는 변수

            // 전문의 전체 갯수를 읽어온다.
            this.connect(GET_TELEGRAM_KEYS_COUNT);
            rs = this.executeQuery();

            if (rs.next()) {
                totalKeyCnt = rs.getInt(1);
            } else {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIMTM003");
				throw new DAOException(errMsg);	//등록된 전문이 없습니다.
            }
            rs.close();

            return totalKeyCnt;
        } catch(Exception e) {
			String errMsg = ExceptionUtil.getErrorCode("BECEAIMTM004");
			throw new DAOException(errMsg);	//전문 총 Count 조회시 오류가 발생하였습니다.
        } finally {
            this.disconnect();
        }
    }

    /**
    * 1. 기능 : TSEAIBM02에서 특정 전문에 해당하는 레코드의 갯수를 반환한다.
    * 2. 처리 개요 : 등록된 전문이 없는 경우 0, 그외 전문의 갯수를 반환한다.
    *
    * 3. 주의사항
    *
    * @return
    * @exception    DAOExcepiton    DB SELECT 관련 SQLException을 포함한 전문 정보를 가져오다 발생되는 모든 에러
    **/
    public int getTelegramFieldCount(String telegramKey) throws DAOException
    {
        try
        {
            ResultSet rs = null;
            int totalKeyCnt = 0;   // Key의 count를 반환하는 변수

            // 전문의 전체 갯수를 읽어온다.
            this.connect(GET_TELEGRAM_FIELD_COUNT);
            this.preparedStatement.setString(1, telegramKey);
            rs = this.executeQuery();

            if (rs.next()) {
                totalKeyCnt = rs.getInt(1);
                logger.debug("필드갯수:" + totalKeyCnt);

            } else {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIMTM005", new String[] {telegramKey});
				throw new DAOException(errMsg);	//전문코드(%1) 의 등록된 전문필드가 없습니다.
            }
            rs.close();

            return totalKeyCnt;

        } catch(Exception e) {
			String errMsg = ExceptionUtil.getErrorCode("BECEAIMTM006", new String[] {telegramKey});
			throw new DAOException(errMsg);	//전문코드(%1) 의 전문필드 총 Count 조회시 오류가 발생하였습니다.
        } finally {
            this.disconnect();
        }
    }
}
