package com.tradevan.gateway.client.task.download;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.validator.GenericValidator;

//import sun.net.www.content.text.Generic;

import com.tradevan.commons.io.FileUtil;
import com.tradevan.gateway.client.dao.bean.TurnkeyMessageLog;
import com.tradevan.gateway.client.dao.bean.TurnkeyMessageLogDetail;
import com.tradevan.gateway.client.dao.service.FromConfigService;
import com.tradevan.gateway.client.dao.service.TurnkeyMessageLogDetailService;
import com.tradevan.gateway.client.dao.service.TurnkeyMessageLogService;
import com.tradevan.gateway.client.dao.service.TurnkeySequenceService;
import com.tradevan.gateway.client.einv.parse.ParserException;
import com.tradevan.gateway.client.einv.parse.ParserHelper;
import com.tradevan.gateway.client.einv.parse.proc.EINVEnvelopeParser;
import com.tradevan.gateway.client.einv.parse.proc.InvoiceEnvelopeParserFactory;
import com.tradevan.gateway.client.einv.sign.SignPayloadException;
import com.tradevan.gateway.client.einv.sign.SignPayloadHelper;
import com.tradevan.gateway.client.einv.transport.CategoryType;
import com.tradevan.gateway.client.einv.transport.ProcessType;
import com.tradevan.gateway.client.einv.util.EncodingType;
import com.tradevan.gateway.client.einv.util.InvoiceConstant;
import com.tradevan.gateway.client.einv.util.InvoiceUtil;
import com.tradevan.gateway.client.einv.validate.ValidateHelper;
import com.tradevan.gateway.client.einv.validate.proc.ValidateConstant;
import com.tradevan.gateway.client.einv.validate.proc.ValidateResult;
import com.tradevan.gateway.client.exception.TurnkeyException;
import com.tradevan.gateway.client.task.Processor;
import com.tradevan.gateway.client.task.info.FileFormat;
import com.tradevan.gateway.client.task.info.ProcPackInfo;
import com.tradevan.gateway.client.task.others.VolumeInfoMaker;
import com.tradevan.gateway.client.util.EnvelopeMakeFactory;
import com.tradevan.gateway.client.util.GatewayUtil;
import com.tradevan.gateway.client.util.MessageIdentifier;
import com.tradevan.gateway.client.util.TaskEnum;
import com.tradevan.gateway.client.util.TurnkeyConstant;
import com.tradevan.gateway.client.util.TurnkeyLogger;
import com.tradevan.gateway.client.util.TurnkeyLoggerHandler;
import com.tradevan.gateway.client.util.TurnkeyUtil;
import com.tradevan.gateway.einv.msg.EINVEnvelope;
import com.tradevan.gateway.einv.msg.EINVPayload;
import com.tradevan.gateway.einv.msg.commBean.ProcessResult;
import com.tradevan.taurus.xdao.XdaoException;

import edu.emory.mathcs.backport.java.util.Arrays;

/**
 * 負責接收所有檔案至指定目錄
 * 
 * @author 2775
 * 
 */
//2012.11.05 移除收方統編與local端資料庫的比對，以達到代收之需求
public class UnpackProcessor extends Processor {
    public static final String TASK = "UNP_M0001";
    private ParserHelper parserHelper = null;
    private ValidateHelper validateHelper = null;
    private String seqToMatchFile = null;
    private SignPayloadHelper signPayloadHelper = null;
    private TurnkeyLoggerHandler logger = TurnkeyLogger.getLogger();

    private void init() {
        if (parserHelper == null)
            parserHelper = new ParserHelper();
        if (validateHelper == null)
            validateHelper = new ValidateHelper();
        if (signPayloadHelper == null)
            signPayloadHelper = new SignPayloadHelper();
    }

    public void setParserHelper(ParserHelper parserHelper) {
        this.parserHelper = parserHelper;
    }

    public void setValidateHelper(ValidateHelper validateHelper) {
        this.validateHelper = validateHelper;
    }

    public void setSignPayloadHelper(SignPayloadHelper signPayloadHelper) {
        this.signPayloadHelper = signPayloadHelper;
    }

    /**
     * 檢查Pack所需的資訊是否充足
     * 
     * @param info
     * @throws Exception
     */
    private void chkProcPackInfo(ProcPackInfo info) throws TurnkeyException {
        TaskEnum task = TaskEnum.Unpack;
        if (info.getSrcPath() == null)
            throw new TurnkeyException(task.getValue()
                    + " : source folder not set!");
        if (info.getTargetPath() == null)
            throw new TurnkeyException(task.getValue()
                    + " : target folder not set!");
        if (info.getFileFormat() == null
                || GenericValidator.isBlankOrNull(info.getFileFormat()
                        .getValue()))
            throw new TurnkeyException(task.getValue()
                    + " : value of file format is invaild");
    }

    /**
     * 處理下載的檔案
     * 
     * @param info
     * @throws TurnkeyException
     */
    public void process(ProcPackInfo info) throws XdaoException, IOException {
        init();
        String methodName = "process";
        try {
            chkProcPackInfo(info);
        } catch (TurnkeyException t) {
            logger.showConsoleError_TaskInfoError(TASK, t, methodName);
            logger.error("chkProcPackInfo occur Exception", t, methodName);
            TurnkeyUtil.insertSysEvent(methodName, null, null, null, t,
                    TurnkeyConstant.ErrorCodeEnum.CONFIG.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys007");
            return;
        }
        File srcDir = info.getSrcPath();
        File[] srcFiles = null;
        // 掃檔前先lock UnpackProcessor.TASK
        synchronized (TASK) {
            srcFiles = TurnkeyUtil.sortFileNameByLastModifiedTime(srcDir);
        }

        if (srcFiles == null)
            return;

        for (File file : srcFiles) {
            if (Processor.isInterruptFlag())
                break;
            if (file.isDirectory()
                    && (!(file.getName().endsWith(
                            TurnkeyConstant.PROCESS_RESULT) || file
                            .getName().endsWith(
                                    TurnkeyConstant.SUMMARY_RESULT))))
                continue;

            // 刪除Proc
            if (info.getProcPath().exists()) {
                File[] procFiles = info.getProcPath().listFiles();
                for (File fileInProc : procFiles)
                    fileInProc.delete();
            } else {
                info.getProcPath().mkdir();
            }

            if (file.getName().endsWith(TurnkeyConstant.PROCESS_RESULT)) {
                FileOutputStream fs = null;
                if (file.isDirectory()) {
                    for (File processResultFile : file.listFiles()) {
                        logger.info("now processing file:"
                                + processResultFile.getName(), methodName);

                        logger.showConsoleInfo_ProcFile(TASK,
                                processResultFile, methodName);
                        byte[] payload = null;
                        try {
                            payload = processSign(processResultFile);
                            ProcessResult processResult = getProcessResult(payload);
                            processProcessResutlt(processResult,
                                    processResultFile.getName(), info);

                            File unsignedFile = new File(info.getProcPath()
                                    + File.separator
                                    + processResultFile.getName());
                            fs = new FileOutputStream(unsignedFile);
                            fs.write(payload);
                            fs.close();

                            logger.showConsoleInfo(TASK, TurnkeyUtil
                                    .getMessage("UTL_M0049")
                                    + unsignedFile, methodName);

                            String path = TurnkeyUtil
                            .moveFileToFolderWithDayTime(
                                    unsignedFile,
                                    info.getBakPath(),
                                    TurnkeyConstant.PROCESS_RESULT,
                                    true);
                            logger.showConsoleInfo_MoveToBAK(TASK,
                                    unsignedFile, new File(path
                                            + File.separator
                                            + unsignedFile.getName()),
                                            methodName);
                            logger.info("move file:"
                                    + unsignedFile.getName()
                                    + " to backup directory, file path="
                                    + path + File.separator
                                    + unsignedFile.getName(), methodName);
                            processResultFile.delete();
                        } catch (TurnkeyException e) {
                            logger
                            .showConsoleError(TASK, TurnkeyUtil
                                    .getMessage("UTL_M0018"), e,
                                    methodName);
                            boolean writeSucess = false;
                            File unsignedFile = null;
                            if (payload != null) {
                                try {
                                    unsignedFile = new File(info
                                            .getProcPath()
                                            + File.separator
                                            + processResultFile.getName());
                                    fs = new FileOutputStream(unsignedFile);
                                    fs.write(payload);
                                    fs.close();
                                    writeSucess = true;
                                } catch (IOException t) {
                                    writeSucess = false;
                                }
                            }
                            String path = null;
                            if (!writeSucess) {
                                path = TurnkeyUtil
                                .moveFileToFolderWithDayTime(
                                        processResultFile,
                                        info.getErrPath(),
                                        TurnkeyConstant.PROCESS_RESULT,
                                        true);
                            } else {
                                path = TurnkeyUtil
                                .moveFileToFolderWithDayTime(
                                        unsignedFile,
                                        info.getErrPath(),
                                        TurnkeyConstant.PROCESS_RESULT,
                                        true);
                                processResultFile.delete();
                            }

                            logger.showConsoleError_MoveToErr(TASK,
                                    processResultFile, new File(path
                                            + File.separator
                                            + processResultFile.getName()),
                                            methodName);

                            logger.error("TurnkeyException: "
                                    + e.getMessage(), e, methodName);
                        } catch (IOException e) {
                            logger.showConsoleError_IO(TASK, e, methodName);
                            logger.error("IOException: " + e.getMessage(),
                                    e, methodName);

                            TurnkeyUtil.insertSysEvent(methodName, null,
                                    null, e,
                                    TurnkeyConstant.ErrorCodeEnum.IO
                                    .getValue(), this.getClass()
                                    .getName(), this.getClass()
                                    .getPackage().getName(),
                            "Sys005");
                            if (!(e instanceof FileNotFoundException))
                                throw e;
                        } catch (XdaoException e) {
                            logger.showConsoleError_Xdao(TASK, e,
                                    methodName);
                            logger.error(
                                    "XDAOException: " + e.getMessage(), e,
                                    methodName);
                            try {
                                TurnkeyUtil.chkDBConnectionReset(e);
                            } catch (XdaoException t) {
                                throw t;
                            }
                            TurnkeyUtil.insertSysEvent(methodName, null,
                                    null, null, e,
                                    TurnkeyConstant.ErrorCodeEnum.DB
                                    .getValue(), this.getClass()
                                    .getName(), this.getClass()
                                    .getPackage().getName(),
                            "Sys006");
                            TurnkeyUtil.moveFileToFolderWithDayTime(processResultFile,
                                    info.getErrPath(),
                                    TurnkeyConstant.PROCESS_RESULT, true);
                        } finally {
                            if (fs != null)
                                fs.close();

                            String[] fileNameInfo = InvoiceUtil
                            .getInvoiceEnvelopeFileNameInfo(processResultFile
                                    .getName());
                            if (fileNameInfo != null
                                    && fileNameInfo.length > 4) {
                                String uuid = fileNameInfo[3];
                                String msgDts = fileNameInfo[2].replaceAll(
                                        "[/-]", "");
                                VolumeInfoMaker.makeVolumeInfoByUUID(
                                        msgDts, uuid);
                            }
                        }
                    }
                }
            } else if (file.getName().endsWith(
                    TurnkeyConstant.SUMMARY_RESULT)) {
                if (file.isDirectory()) {
                    FileOutputStream fs = null;
                    for (File summaryResultFile : file.listFiles()) {
                        logger.info("now processing file:"
                                + summaryResultFile.getName(), methodName);
                        logger.showConsoleInfo_ProcFile(TASK,
                                summaryResultFile, methodName);
                        try {
                            byte[] payloads = processSign(summaryResultFile);
                            File unsignedFile = new File(info.getProcPath()
                                    + File.separator
                                    + summaryResultFile.getName());
                            fs = new FileOutputStream(unsignedFile);
                            fs.write(payloads);
                            fs.close();
                            logger.showConsoleInfo(TASK, TurnkeyUtil
                                    .getMessage("UTL_M0049")
                                    + unsignedFile, methodName);

                            String path = TurnkeyUtil
                            .moveFileToFolderWithDayTime(
                                    unsignedFile,
                                    info.getBakPath(),
                                    TurnkeyConstant.SUMMARY_RESULT,
                                    true);

                            logger.showConsoleInfo_MoveToBAK(TASK,
                                    unsignedFile, new File(path
                                            + File.separator
                                            + unsignedFile.getName()),
                                            methodName);

                            logger.info("move file:"
                                    + unsignedFile.getName()
                                    + " to backup directory, file path="
                                    + path + File.separator
                                    + unsignedFile.getName(), methodName);
                            summaryResultFile.delete();

                        } catch (TurnkeyException e) {
                            logger
                            .showConsoleError(TASK, TurnkeyUtil
                                    .getMessage("UTL_M0018"), e,
                                    methodName);

                            String path = TurnkeyUtil
                            .moveFileToFolderWithDayTime(
                                    summaryResultFile, info
                                    .getErrPath(),
                                    TurnkeyConstant.SUMMARY_RESULT,
                                    true);

                            logger.showConsoleError_MoveToErr(TASK,
                                    summaryResultFile, new File(path
                                            + File.separator
                                            + summaryResultFile.getName()),
                                            methodName);

                            logger.error("TurnkeyException: "
                                    + e.getMessage(), e, methodName);
                        } catch (XdaoException e) {
                            logger.showConsoleError_Xdao(TASK, e,
                                    methodName);
                            logger.error(
                                    "XDAOException: " + e.getMessage(), e,
                                    methodName);
                            try {
                                TurnkeyUtil.chkDBConnectionReset(e);
                            } catch (XdaoException t) {
                                throw t;
                            }
                            TurnkeyUtil.insertSysEvent(methodName, null,
                                    null, null, e,
                                    TurnkeyConstant.ErrorCodeEnum.DB
                                    .getValue(), this.getClass()
                                    .getName(), this.getClass()
                                    .getPackage().getName(),
                            "Sys006");
                            
                            String path = TurnkeyUtil
                            .moveFileToFolderWithDayTime(
                                    summaryResultFile, info
                                    .getErrPath(),
                                    TurnkeyConstant.SUMMARY_RESULT,
                                    true);

                            logger.showConsoleError_MoveToErr(TASK,
                                    summaryResultFile, new File(path
                                            + File.separator
                                            + summaryResultFile.getName()),
                                            methodName);
                        } catch (IOException e) {
                            logger.showConsoleError_IO(TASK, e, methodName);
                            logger.error("IOException: " + e.getMessage(),
                                    e, methodName);

                            TurnkeyUtil.insertSysEvent(methodName, null,
                                    null, e,
                                    TurnkeyConstant.ErrorCodeEnum.IO
                                    .getValue(), this.getClass()
                                    .getName(), this.getClass()
                                    .getPackage().getName(),
                            "Sys005");
                            if (!(e instanceof FileNotFoundException))
                                throw e;
                        } finally {
                            if (fs != null)
                                fs.close();
                        }
                    }
                }
            } else {
                try {
                    logger.info("now processing file:" + file.getName(),
                            methodName);
                    logger.showConsoleInfo_ProcFile(TASK, file, methodName);
                    processEnvelope(file, info);
                } catch (TurnkeyException e) {
                    logger.showConsoleError(TASK, TurnkeyUtil
                            .getMessage("UTL_M0018"), e, methodName);

                    String path = TurnkeyUtil.moveFileToFolderWithDayTime(
                            file, info.getErrPath(), null, true);
                    logger.error("TurnkeyException: " + e.getMessage(), e,
                            methodName);
                    logger.info("move file:" + file.getName()
                            + " to error directory, file path=" + path
                            + File.separator + file.getName(), methodName);

                    logger.showConsoleError_MoveToErr(TASK, file, new File(
                            path + File.separator + file.getName()),
                            methodName);

                    TurnkeyMessageLogService.INSTANCE
                    .updatePathOfMessageLogDtl(seqToMatchFile,
                            null, path + File.separator
                            + file.getName(),
                            TaskEnum.Unpack.getValue());
                } catch (XdaoException e) {
                    logger.showConsoleError_Xdao(TASK, e, methodName);
                    logger.error("XDAOException: " + e.getMessage(), e,
                            methodName);
                    try {
                        TurnkeyUtil.chkDBConnectionReset(e);
                    } catch (XdaoException t) {
                        throw t;
                    }
                    String path = TurnkeyUtil.moveFileToFolderWithDayTime(
                            file, info.getErrPath(), null, true);
                    TurnkeyMessageLogService.INSTANCE
                    .updatePathOfMessageLogDtl(seqToMatchFile,
                            null, path + File.separator
                            + file.getName(),
                            TaskEnum.Unpack.getValue());
                    TurnkeyUtil.insertSysEvent(methodName, null, null,
                            null, e, TurnkeyConstant.ErrorCodeEnum.DB
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(),
                    "Sys006");
                }
            }
        }
    }

    /**
     * 處理信封檔案資訊
     * 
     * @param file
     * @param info
     * @throws TurnkeyException
     * @throws XdaoException
     */
    @SuppressWarnings( { "rawtypes" })
    private void processEnvelope(File file, ProcPackInfo info)
    throws TurnkeyException, XdaoException, IOException {
        String methodName = "processEnvelope";
        int errCode = 0;
        if ((errCode = InvoiceUtil.chkInvoiceEnvelopeFileName((file.getName()
                .split("_"))[0])) != 0) {
            TurnkeyException e = new TurnkeyException(
                    "file name/format is invalid" + file.getName()
                    + " , errorCode =" + errCode);
            TurnkeyUtil.insertSysEvent(methodName, null, null, e,
                    TurnkeyConstant.ErrorCodeEnum.FILE_NAME_FORMAT.getValue(),
                    this.getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys008");
            throw e;
        }
        String[] nameInfo = InvoiceUtil.getInvoiceEnvelopeFileNameInfo(file
                .getName().split("_")[0]);
        // 驗章作業
        byte[] payload = processSign(file);
        Class clazz = null;
        try {
            clazz = EnvelopeMakeFactory.getEINVEnvelopeClass(nameInfo[0]);
        } catch (ClassNotFoundException e) {
            logger.showConsoleError(TASK, TurnkeyUtil.getMessage("UTL_M0050"),
                    e, methodName);
            TurnkeyException t = new TurnkeyException("file version = "
                    + nameInfo[0] + " is invalid or not support");
            TurnkeyUtil.insertSysEvent(methodName, null, nameInfo[3], e,
                    TurnkeyConstant.ErrorCodeEnum.VERSION_NOT_SUPPORT
                    .getValue(), this.getClass().getName(), this
                    .getClass().getPackage().getName(), "Sys019");
            MessageIdentifier mi = new MessageIdentifier();
            TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
            msgLog.setSeqno(file.getName().split("_")[1]);
            if (TurnkeyMessageLogService.INSTANCE.queryMessageLog(msgLog)
                    .size() > 0) {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                TurnkeyMessageLogService.INSTANCE.updMessageLogBySeq(msgLog);
            } else {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                msgLog.setSeqno(file.getName().split("_")[1]);
                msgLog.setSubseqno(mi.getMessageSubId(1));
                msgLog.setUuid(nameInfo[3]);
                msgLog.setCharacterCount(String.valueOf(file.length()));
                msgLog.setInOutBound(TurnkeyConstant.INBOUND);
                msgLog.setMessageDts(GatewayUtil.getDate());
                msgLog.setMessageType(nameInfo[1]);
                msgLog.setProcessType(ProcessType.EXCHANGE.getValue());
                TurnkeyMessageLogService.INSTANCE.insUpdMessageLog(msgLog);
            }
            TurnkeyMessageLogDetail msgDtl = new TurnkeyMessageLogDetail();
            msgDtl.setFilename(file.getAbsolutePath());
            msgDtl.setSeqno(msgLog.getSeqno());
            msgDtl.setSubseqno(mi.getMessageSubId(1));
            msgDtl.setProcessDts(GatewayUtil.getDate());
            msgDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
            msgDtl.setTask(TaskEnum.Unpack.getValue());
            TurnkeyMessageLogService.INSTANCE.updMessageLogDetail(msgDtl);
            throw t;
        }
        seqToMatchFile = null;
        String procDir = processUnpack(file.getName(), file, payload, clazz, info);

        String bakPath;

        File tarDir = new File(info.getTargetPath() + File.separator
                + TurnkeyConstant.SRC);
        if (!tarDir.exists()) {
            tarDir.mkdirs();
        }
        File tarFile = new File(tarDir + File.separator + file.getName());
        if (tarFile.exists()) {
            logger.showConsoleError(TASK, TurnkeyUtil.getMessage("UTL_M0014")
                    + tarFile, methodName);
            logger.error("target file:" + tarFile.getAbsolutePath()
                    + " already existed", methodName);
            IOException t = new IOException("target file:"
                    + tarFile.getAbsolutePath() + " already existed");
            // String path = TurnkeyUtil.moveFileToFolderWithDayTime(new
            // File(info.getProcPath().getPath()
            // + File.separator + file.getName()), info.getErrPath(), null,
            // true);
            TurnkeyUtil.insertSysEvent(methodName, null, null, null, t,
                    TurnkeyConstant.ErrorCodeEnum.IO.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys009");

            MessageIdentifier mi = new MessageIdentifier();
            TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
            msgLog.setSeqno(file.getName().split("_")[1]);
            if (TurnkeyMessageLogService.INSTANCE.queryMessageLog(msgLog)
                    .size() > 0) {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                TurnkeyMessageLogService.INSTANCE.updMessageLogBySeq(msgLog);
            } else {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                msgLog.setSeqno(file.getName().split("_")[1]);
                msgLog.setSubseqno(mi.getMessageSubId(1));
                msgLog.setUuid(nameInfo[3]);
                msgLog.setCharacterCount(String.valueOf(file.length()));
                msgLog.setInOutBound(TurnkeyConstant.INBOUND);
                msgLog.setMessageDts(GatewayUtil.getDate());
                msgLog.setMessageType(nameInfo[1]);
                msgLog.setProcessType(ProcessType.EXCHANGE.getValue());
                TurnkeyMessageLogService.INSTANCE.insUpdMessageLog(msgLog);
            }
            TurnkeyMessageLogDetail msgDtl = new TurnkeyMessageLogDetail();
            msgDtl.setFilename(file.getAbsolutePath());
            msgDtl.setSeqno(msgLog.getSeqno());
            msgDtl.setSubseqno(mi.getMessageSubId(1));
            msgDtl.setProcessDts(GatewayUtil.getDate());
            msgDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
            msgDtl.setTask(TaskEnum.Unpack.getValue());
            TurnkeyMessageLogService.INSTANCE.updMessageLogDetail(msgDtl);
            throw t;
        } else {
            // 搬檔前先lock DownCastProcessor.TASK
            synchronized (DownCastProcessor.TASK) {
                FileUtil.move(new File(procDir), tarDir);
            }
            logger.info("make target file:"
                    + info.getProcPath().getAbsolutePath() + File.separator
                    + file.getName(), methodName);

            logger.showConsoleInfo_MoveToTarget(TASK, file, new File(info
                    .getProcPath().getAbsolutePath()
                    + File.separator + file.getName()), methodName);

            bakPath = TurnkeyUtil.moveFileToFolderWithDayTime(file, info
                    .getBakPath(), null, true);
            logger.info("move file:" + file.getName()
                    + " to backup directory, filePath=" + bakPath
                    + File.separator + file.getName(), methodName);
            logger.showConsoleInfo_MoveToBAK(TASK, file, new File(bakPath
                    + File.separator + file.getName()), methodName);
        }

        // bakPath = TurnkeyUtil.moveFileToFolderWithDayTime(file,
        // info.getBakPath(), null, true);
        // logger.showConsoleInfo_MoveToBAK(TASK, file, new File(bakPath +
        // File.separator + file.getName()), methodName);

        try {
            TurnkeyMessageLogService.INSTANCE.updatePathOfMessageLogDtl(
                    seqToMatchFile, null, bakPath + File.separator
                    + file.getName(), TaskEnum.Unpack.getValue());
        } catch (XdaoException t) {
            logger.showConsoleError_Xdao(TASK, t, methodName);
            logger.error("XDAOException: " + t.getMessage(), t, methodName);
            try {
                TurnkeyUtil.chkDBConnectionReset(t);
            } catch (XdaoException e) {
                throw e;
            }
            TurnkeyUtil.insertSysEvent(methodName, null, null, null, t,
                    TurnkeyConstant.ErrorCodeEnum.DB.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys006");
            MessageIdentifier mi = new MessageIdentifier();
            TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
            msgLog.setSeqno(file.getName().split("_")[1]);
            if (TurnkeyMessageLogService.INSTANCE.queryMessageLog(msgLog)
                    .size() > 0) {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                TurnkeyMessageLogService.INSTANCE.updMessageLogBySeq(msgLog);
            } else {
                msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                msgLog.setSeqno(file.getName().split("_")[1]);
                msgLog.setSubseqno(mi.getMessageSubId(1));
                msgLog.setUuid(nameInfo[3]);
                msgLog.setCharacterCount(String.valueOf(file.length()));
                msgLog.setInOutBound(TurnkeyConstant.INBOUND);
                msgLog.setMessageDts(GatewayUtil.getDate());
                msgLog.setMessageType(nameInfo[1]);
                msgLog.setProcessType(ProcessType.EXCHANGE.getValue());
                TurnkeyMessageLogService.INSTANCE.insUpdMessageLog(msgLog);
            }
            TurnkeyMessageLogDetail msgDtl = new TurnkeyMessageLogDetail();
            msgDtl.setFilename(file.getAbsolutePath());
            msgDtl.setSeqno(msgLog.getSeqno());
            msgDtl.setSubseqno(mi.getMessageSubId(1));
            msgDtl.setProcessDts(GatewayUtil.getDate());
            msgDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
            msgDtl.setTask(TaskEnum.Unpack.getValue());
            TurnkeyMessageLogService.INSTANCE.updMessageLogDetail(msgDtl);

            String errPath = TurnkeyUtil.moveFileToFolderWithDayTime(file, info
                    .getErrPath(), null, true);
            logger.info("move file:" + file.getName()
                    + " to error directory, filePath=" + errPath
                    + File.separator + file.getName(), methodName);
            logger.showConsoleError_MoveToErr(TASK, file, new File(errPath
                    + File.separator + file.getName()), methodName);
        }

    }

    /**
     * 處理拆封
     * 
     * @param fileName
     * @param payload
     * @param clazz
     * @param info
     * @return 
     * @throws TurnkeyException
     * @throws XdaoException
     */
    @SuppressWarnings( { "rawtypes", "unchecked" })
    private String processUnpack(String fileName, File file, byte[] payload,
            Class clazz, ProcPackInfo info) throws TurnkeyException,
            XdaoException, IOException {
        String methodName = "processUnpack";
        List<ValidateResult> vrList = validateHelper.validateEnvelope(payload);

        String[] oriFileInfo = fileName.split("_");
        String[] fileNameInfo = InvoiceUtil
        .getInvoiceEnvelopeFileNameInfo(oriFileInfo[0]);
        String uuid = fileNameInfo[3];
        MessageIdentifier mi = new MessageIdentifier();
        String seqNo = "";

        String fromRoutingId = "";
        String toRoutingId = "";

        if (vrList.size() > 0) {
            EINVEnvelopeParser envelopeParser = InvoiceEnvelopeParserFactory
            .getInvoiceEnvelopeParser(fileNameInfo[0]);
            if (envelopeParser != null) {
                BufferedInputStream bis = null;
                try {
                    bis = new BufferedInputStream(new ByteArrayInputStream(
                            payload));
                    envelopeParser.setInputStream(bis);
                    String xml = envelopeParser
                    .parserInvoiceEnvelope(fileNameInfo[0] + "."
                            + fileNameInfo[1]);
                    EINVEnvelope envelope = (EINVEnvelope) parserHelper
                    .unmarshalFromXML(xml, fileNameInfo[0],
                            InvoiceConstant.INVOICE_ENVELOPE);
                    fromRoutingId = envelope.getFromVacRoutingId();
                    toRoutingId = envelope.getToVacRoutingId();
                } catch (ParserException e) {
                    logger.showConsoleError(TASK, TurnkeyUtil
                            .getMessage("UTL_M0019")
                            + ": " + fileName, methodName);
                    TurnkeyException t = new TurnkeyException(
                            "Invoice envelope unmarshal fail: ", e);
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, t,
                            TurnkeyConstant.ErrorCodeEnum.INVOICE_INVAILD
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys001");
                    throw t;
                } finally {
                    if (bis != null)
                        bis.close();
                }
            }
        }

        //取不到seqno的情況
        if (oriFileInfo.length < 2
        		|| GenericValidator
        		.isBlankOrNull(oriFileInfo[oriFileInfo.length - 1])){
        	//2012.11.05 2775 bug fix: get wrong message id 
        	seqNo = TurnkeySequenceService.INSTANCE.getNextSequence();
        }else{
        	seqNo = oriFileInfo[oriFileInfo.length - 1];
        }
        
        File xmlDir = null;
        xmlDir = new File(info.getProcPath() + File.separator
                + oriFileInfo[0] + "_" + seqNo);
        
        for (int i = 0; i < vrList.size(); i++) {
            boolean processFail = false;
            if (Processor.isInterruptFlag())
                break;

            ValidateResult vr = vrList.get(i);
            String xml = "";
            String fromPartyId = "";
            String toPartyId = "";
            String invoiceIdentifier = "";
            String path = "";
            String subSeqNo = mi.getMessageSubId(i + 1);

            if (vr.getErrorCode() == ValidateConstant.SUCESS[0]) {
                if (vr.getMessage() instanceof EINVPayload) {
                    fromPartyId = ((EINVPayload) vr.getMessage()).getFromBan();
                    toPartyId = ((EINVPayload) vr.getMessage()).getToBan();
                    invoiceIdentifier = ((EINVPayload) vr.getMessage())
                    .getInvoiceIdentifier();
                    //2012.11.05 移除收方統編與local端資料庫的比對，以達到代收之需求
//                    if (FromConfigService.INSTANCE
//                            .getFromConfigByBan(toPartyId) == null) {
//                        logger.showConsoleError(TASK, TurnkeyUtil
//                                .getMessage("UTL_M0051"), methodName);
//                        TurnkeyException e = new TurnkeyException(
//                        "Receiver is not match in the local Database");
//                        TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
//                                TurnkeyConstant.ErrorCodeEnum.INVOICE_INVAILD
//                                .getValue(), this.getClass().getName(),
//                                this.getClass().getPackage().getName(),
//                        "Sys001");
//
//                        if (vrList.size() == 1) {
//                            throw e;
//                        }
//                        continue;
//                    }
                }

                try {
                    xml = parserHelper.marshalToXML(vr.getMessage());
                } catch (ParserException e) {
                    logger.showConsoleError(TASK, TurnkeyUtil
                            .getMessage("UTL_M0019")
                            + file, e, methodName);
                    TurnkeyException t = new TurnkeyException(
                    "Marshal to xml fail!");
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
                            TurnkeyConstant.ErrorCodeEnum.PARSER.getValue(),
                            this.getClass().getName(), this.getClass()
                            .getPackage().getName(), "Sys002");
                    throw t;
                    // 不會發生才對
                }
            } else {
                if (ValidateConstant.ENVELOPE_UNMARSHAL_FAIL[0].equals(vr
                        .getErrorCode())) {

                    TurnkeyException t = new TurnkeyException(
                            "Invoice envelope unmarshal fail: "
                            + vr.getException().getMessage(), vr
                            .getException());
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, t,
                            TurnkeyConstant.ErrorCodeEnum.INVOICE_INVAILD
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys001");
                    throw t;
                } else {
                    xmlDir = new File(info.getErrPath() + File.separator
                            + oriFileInfo[0] + "_" + seqNo);

                    xml = vr.getFailString();
                    TurnkeyException t = new TurnkeyException(
                            "Invoice message unmarshal fail:" + xml);
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, t,
                            TurnkeyConstant.ErrorCodeEnum.INVOICE_INVAILD
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys001");
                    processFail = true;
                }
            }

            try {
                // if (info.getFileFormat() == FileFormat.FlatFile) {
                path = xmlDir.getAbsoluteFile() + File.separator + seqNo + "-"
                + subSeqNo + ".xml";
                xmlDir.mkdir();
                File targetFile = new File(path);
                if (targetFile.exists()) {
                    logger.showConsoleError(TASK, TurnkeyUtil
                            .getMessage("UTL_M0014")
                            + targetFile, methodName);
                    logger.error("TargetFile: " + targetFile.getAbsolutePath()
                            + " already existed!", methodName);
                    IOException e = new IOException("TargetFile: "
                            + targetFile.getAbsolutePath()
                            + " already existed!");
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
                            TurnkeyConstant.ErrorCodeEnum.IO.getValue(), this
                            .getClass().getName(), this.getClass()
                            .getPackage().getName(), "Sys009");
                    try {
                        updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info,
                                xmlDir, xml, fileNameInfo, fromPartyId,
                                toPartyId, path, true, invoiceIdentifier,
                                fromRoutingId, toRoutingId);
                    } catch (IOException ie) {
                        TurnkeyUtil.insertSysEvent(methodName, null, seqNo,
                                subSeqNo, ie, TurnkeyConstant.ErrorCodeEnum.IO
                                .getValue(), this.getClass().getName(),
                                this.getClass().getPackage().getName(),
                        "Sys005");
                        updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info,
                                xmlDir, xml, fileNameInfo, fromPartyId,
                                toPartyId, null, processFail,
                                invoiceIdentifier, fromRoutingId, toRoutingId);
                        throw ie;
                    }
                    throw e;
                } else {
                    try {
                        FileUtil.write(targetFile, xml
                                .getBytes(EncodingType.UTF8.getValue()));
                        logger.showConsoleInfo(TASK, TurnkeyUtil
                                .getMessage("UTL_M0049")
                                + targetFile, methodName);
                        logger.info("make target file to "
                                + targetFile.getAbsolutePath(), methodName);
                    } catch (IOException ie) {
                        TurnkeyUtil.insertSysEvent(methodName, null, seqNo,
                                subSeqNo, ie, TurnkeyConstant.ErrorCodeEnum.IO
                                .getValue(), this.getClass().getName(),
                                this.getClass().getPackage().getName(),
                        "Sys005");
                        updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info,
                                xmlDir, xml, fileNameInfo, fromPartyId,
                                toPartyId, null, processFail,
                                invoiceIdentifier, fromRoutingId, toRoutingId);
                        throw ie;
                    }
                }
                // }
                try {
                    updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info,
                            xmlDir, xml, fileNameInfo, fromPartyId, toPartyId,
                            path, processFail, invoiceIdentifier,
                            fromRoutingId, toRoutingId);
                } catch (IOException ie) {
                    TurnkeyUtil.insertSysEvent(methodName, null, seqNo,
                            subSeqNo, ie, TurnkeyConstant.ErrorCodeEnum.IO
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys005");
                    updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info,
                            xmlDir, xml, fileNameInfo, fromPartyId, toPartyId,
                            null, processFail, invoiceIdentifier,
                            fromRoutingId, toRoutingId);
                    if (!(ie instanceof FileNotFoundException))
                        throw ie;
                }
                seqToMatchFile = seqNo;
            } catch (XdaoException e) {
                logger.showConsoleError_Xdao(TASK, e, methodName);
                logger.error("XdaoException: " + e.getMessage(), methodName);
                try {
                    TurnkeyUtil.chkDBConnectionReset(e);
                } catch (XdaoException t) {
                    throw t;
                }
                TurnkeyUtil.insertSysEvent(methodName, null, seqNo, subSeqNo,
                        e, TurnkeyConstant.ErrorCodeEnum.DB.getValue(), this
                        .getClass().getName(), this.getClass()
                        .getPackage().getName(), "Sys006");
                updateMsgLogAndMsgLogDtl(uuid, seqNo, subSeqNo, info, xmlDir,
                        xml, fileNameInfo, fromPartyId, toPartyId, null,
                        processFail, invoiceIdentifier, fromRoutingId,
                        toRoutingId);
            }
        }
        // File targetFileDir = new File(info.getTargetPath() + File.separator +
        // TurnkeyConstant.SRC + File.separator
        // + oriFileInfo[0] + "_" + seqToMatchFile);
        // if (!targetFileDir.exists())
        // targetFileDir.mkdirs();
        //            
        // File targetFile = new File(targetFileDir + File.separator +
        // oriFileInfo[0]);
        // if (targetFile.exists()) {
        // logger.showConsoleError(TASK, TurnkeyUtil.getMessage("UTL_M0014") +
        // targetFile, methodName);
        // logger.error("TargetFile: " + targetFile.getAbsolutePath() +
        // " already existed!", methodName);
        // IOException e = new IOException("TargetFile: " +
        // targetFile.getAbsolutePath() + " already existed!");
        // TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
        // TurnkeyConstant.ErrorCodeEnum.IO.getValue(), this
        // .getClass().getName(), this.getClass().getPackage().getName(),
        // "Sys009");
        // throw e;
        // } else {
        // try {
        // FileUtil.write(targetFile, payload);
        // logger.showConsoleInfo(TASK, TurnkeyUtil.getMessage("UTL_M0049") +
        // targetFile, methodName);
        // logger.info("make target file:" + targetFile.getAbsolutePath(),
        // methodName);
        // } catch (IOException e) {
        // TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
        // TurnkeyConstant.ErrorCodeEnum.IO.getValue(),
        // this.getClass().getName(), this.getClass().getPackage().getName(),
        // "Sys005");
        // throw e;
        // }
        // }
        return xmlDir.getAbsolutePath();
    }

    private void updateMsgLogAndMsgLogDtl(String uuid, String seqNo,
            String subSeqNo, ProcPackInfo info, File xmlDir, String xml,
            String[] fileNameInfo, String fromPartyId, String toPartyId,
            String path, boolean processFail, String invoiceIdentifier,
            String fromRoutingId, String toRoutingId) throws IOException,
            XdaoException {
        TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
        msgLog.setUuid(uuid);
        msgLog.setSeqno(seqNo);
        msgLog.setSubseqno(subSeqNo);
        msgLog.setMessageType(fileNameInfo[1]);
        msgLog.setCategoryType(CategoryType.B2B);
        msgLog.setProcessType(ProcessType.EXCHANGE.getValue());
        msgLog.setFromPartyId(fromPartyId);
        msgLog.setToPartyId(toPartyId);
        msgLog.setFromRoutingId(fromRoutingId);
        msgLog.setToRoutingId(toRoutingId);
        msgLog.setMessageDts(GatewayUtil.getDateTime());
        msgLog.setCharacterCount(String.valueOf(xml.getBytes(EncodingType.UTF8
                .getValue()).length));
        if (!processFail)
            msgLog.setStatus(TurnkeyConstant.STATUS_PROCESS);
        else
            msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
        msgLog.setInOutBound(TurnkeyConstant.INBOUND);
        msgLog.setInvoiceIdentifier(invoiceIdentifier);
        TurnkeyMessageLogService.INSTANCE.insUpdMessageLog(msgLog);
        TurnkeyMessageLogDetail msgLogDtl = new TurnkeyMessageLogDetail();
        msgLogDtl.setSeqno(msgLog.getSeqno());
        msgLogDtl.setSubseqno(msgLog.getSubseqno());
        msgLogDtl.setProcessDts(GatewayUtil.getDateTime());
        msgLogDtl.setTask(TaskEnum.Unpack.getValue());
        if (!processFail)
            msgLogDtl.setStatus(TurnkeyConstant.STATUS_SUCCESS);
        else
            msgLogDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
        msgLogDtl.setFilename(path);
        TurnkeyMessageLogService.INSTANCE.updMessageLogDetail(msgLogDtl);

    }

    /**
     * 驗章
     * 
     * @return
     * @throws XdaoException
     */
    private byte[] processSign(File file) throws TurnkeyException,
    XdaoException {
        String methodName = "processSign";
        String signPayload;
        try {
            logger.showConsoleInfo(TASK, TurnkeyUtil.getMessage("UTL_M0052")
                    + file, methodName);
            signPayload = FileUtil.readFileToString(file, EncodingType.UTF8
                    .getValue());
            return signPayloadHelper.verify(signPayload);
        } catch (IOException e) {
            logger.error("IOException: " + e.getMessage(), e, methodName);
            TurnkeyException t = new TurnkeyException(
                    "read signed file occur exception", e);
            TurnkeyUtil.insertSysEvent(methodName, null, null, e,
                    TurnkeyConstant.ErrorCodeEnum.IO.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys005");
            throw t;
        } catch (SignPayloadException e) {
            logger.error("SignPayloadException: " + e.getMessage(), e,
                    methodName);
            TurnkeyException t = new TurnkeyException(
                    "verify signed file occur exception", e);
            TurnkeyUtil.insertSysEvent(methodName, null, null, e,
                    TurnkeyConstant.ErrorCodeEnum.SIGN.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys020");
            throw t;

        }
    }

    private ProcessResult getProcessResult(byte[] payload)
    throws TurnkeyException, XdaoException {
        String methodName = "getProcessResult";
        ProcessResult result = null;
        try {
            result = (ProcessResult) parserHelper.unmarshalFromXML(payload,
                    ProcessResult.class);
        } catch (ParserException e) {
            logger.error("ParserException: " + e.getMessage(), e, methodName);
            TurnkeyException t = new TurnkeyException(
                    "Parse ProcessResult fail", e);
            TurnkeyUtil.insertSysEvent(methodName, null, null, e,
                    TurnkeyConstant.ErrorCodeEnum.PARSER.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys002");
            throw t;
        }
        return result;
    }

    private void processProcessResutlt(ProcessResult processResult,
            String fileName, ProcPackInfo procPackInfo)
    throws TurnkeyException, XdaoException {
        String methodName = "processProcessResutlt";
        try {

            String[] fileNameInfo = InvoiceUtil
            .getInvoiceEnvelopeFileNameInfo(fileName);
            if (fileNameInfo == null) {
                TurnkeyException t = new TurnkeyException(
                        "Invaild processResult file name: " + fileName);
                TurnkeyUtil
                .insertSysEvent(methodName, null, null, t,
                        TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                        .getValue(), this.getClass().getName(),
                        this.getClass().getPackage().getName(),
                "Sys008");
                throw t;
            }
            String uuid = fileNameInfo[3];
            String msgDts = fileNameInfo[2];
            msgDts = msgDts.replaceAll("-", "");
            TurnkeyMessageLog messageLog = new TurnkeyMessageLog();
            messageLog.setUuid(uuid);
            messageLog.setMessageDts(msgDts);
            List<TurnkeyMessageLog> queryList = TurnkeyMessageLogService.INSTANCE
            .queryMessageLog(messageLog);
            // 2011/11/01 fix 收到ProcessResult若只有1筆，會造成寫出兩筆訊息記錄
            if ((queryList != null && queryList.size() > 0)
                    && (!(queryList.size() == 1 && GenericValidator
                            .isBlankOrNull(queryList.get(0)
                                    .getInvoiceIdentifier())))) {
                if (processResult.getResult() == null
                        || processResult.getResult().getInfo() == null) {
                    TurnkeyException e = new TurnkeyException(
                    "ProcessResult can not parser");
                    TurnkeyUtil.insertSysEvent(methodName, null, uuid, e,
                            TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys021");
                    throw e;
                }

                if (processResult.getResult().getInfo().size() == 1) {
                    com.tradevan.gateway.einv.msg.commBean.ProcessResultBody.Info info = processResult
                    .getResult().getInfo().get(0);
                    if (!GenericValidator.isBlankOrNull(info.getCode())) {
                        if (info.getCode().equals(
                                TurnkeyConstant.PROCESS_SUCCESS)) {// 中心端回報成功
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_CONFIRM);
                        } else if (info.getCode().equals(
                                ValidateConstant.ENVELOPE_UNMARSHAL_FAIL)// 整個封套有誤
                                || info.getCode().equals(
                                        TurnkeyConstant.SIGN_ERROR_CODE)) {
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_ERROR);
                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));
                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    uuid,
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                        } else if (Arrays
                                .asList(TurnkeyConstant.FTP_ERROR_CODE)
                                .contains(info.getCode())) {
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_ERROR);
                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));
                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    uuid,
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                        } else {
                            if ("E".equals(processResult.getMessageInfoType()
                                    .getService())) {
                                TurnkeyMessageLogService.INSTANCE
                                .updateStatusMessageLogByUUID(uuid,
                                        msgDts,
                                        TurnkeyConstant.OUTBOUND,
                                        TurnkeyConstant.STATUS_ERROR);
                            } else {
                                TurnkeyMessageLogService.INSTANCE
                                .updateStatusMessageLogByUUID(uuid,
                                        msgDts,
                                        TurnkeyConstant.OUTBOUND,
                                        TurnkeyConstant.STATUS_CONFIRM);
                            }
                            String messageID = processResult
                            .getMessageInfoType().getMessageType()
                            + processResult.getResult().getInfo()
                            .get(0).getParameter0()
                            + processResult.getResult().getInfo()
                            .get(0).getParameter1();

                            TurnkeyMessageLog predicate = new TurnkeyMessageLog();
                            predicate.setInvoiceIdentifier(messageID);
                            predicate.setUuid(uuid);
                            List<TurnkeyMessageLog> queryForUpdateList = TurnkeyMessageLogService.INSTANCE
                            .queryMessageLog(predicate);
                            if (queryForUpdateList == null
                                    || queryForUpdateList.size() == 0) {
                                TurnkeyMessageLogService.INSTANCE
                                .updateStatusMessageLogByUUID(uuid,
                                        msgDts,
                                        TurnkeyConstant.OUTBOUND,
                                        TurnkeyConstant.STATUS_ERROR);
                                TurnkeyException e = new TurnkeyException(
                                        TurnkeyUtil
                                        .getProcessResultMessage(info));
                                TurnkeyUtil
                                .insertSysEvent(
                                        methodName,
                                        null,
                                        uuid,
                                        e,
                                        TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                        .getValue(), this
                                        .getClass().getName(),
                                        this.getClass().getPackage()
                                        .getName(), "Sys021",
                                        info.getCode() + " ; "
                                        + info.getDescription());
                            } else {
                                //								TurnkeyMessageLog msgLog = queryForUpdateList
                                //										.get(0);

                                for(TurnkeyMessageLog msgLog: queryForUpdateList){
                                    msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                                    TurnkeyMessageLogService.INSTANCE
                                    .updMessageLogBySeqSubseq(msgLog);

                                    TurnkeyException e = new TurnkeyException(
                                            TurnkeyUtil
                                            .getProcessResultMessage(info));
                                    TurnkeyUtil
                                    .insertSysEvent(
                                            methodName,
                                            null,
                                            msgLog.getSeqno(),
                                            msgLog.getSubseqno(),
                                            e,
                                            TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                            .getValue(), this
                                            .getClass().getName(),
                                            this.getClass().getPackage()
                                            .getName(), "Sys021",
                                            info.getCode() + " ; "
                                            + info.getDescription());
                                }
                            }
                        }
                    }
                } else {
                    if ("E".equals(processResult.getMessageInfoType()
                            .getService())) {
                        TurnkeyMessageLogService.INSTANCE
                        .updateStatusMessageLogByUUID(uuid, msgDts,
                                TurnkeyConstant.OUTBOUND,
                                TurnkeyConstant.STATUS_ERROR);
                    } else {
                        TurnkeyMessageLogService.INSTANCE
                        .updateStatusMessageLogByUUID(uuid, msgDts,
                                TurnkeyConstant.OUTBOUND,
                                TurnkeyConstant.STATUS_CONFIRM);
                    }
                    for (com.tradevan.gateway.einv.msg.commBean.ProcessResultBody.Info info : processResult
                            .getResult().getInfo()) {
                        if (info != null) {
                            String messageID = processResult
                            .getMessageInfoType().getMessageType()
                            + info.getParameter0()
                            + info.getParameter1();

                            TurnkeyMessageLog predicate = new TurnkeyMessageLog();
                            predicate.setInvoiceIdentifier(messageID);
                            predicate.setUuid(uuid);
                            List<TurnkeyMessageLog> queryForUpdateList = TurnkeyMessageLogService.INSTANCE
                            .queryMessageLog(predicate);
                            if (queryForUpdateList == null
                                    || queryForUpdateList.size() == 0) {
                                TurnkeyException e = new TurnkeyException(
                                        TurnkeyUtil
                                        .getProcessResultMessage(info));
                                TurnkeyUtil
                                .insertSysEvent(
                                        methodName,
                                        null,
                                        uuid,
                                        e,
                                        TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                        .getValue(), this
                                        .getClass().getName(),
                                        this.getClass().getPackage()
                                        .getName(), "Sys023",
                                        info.getCode() + " ; "
                                        + info.getDescription());
                            } else {
                                //								TurnkeyMessageLog msgLog = queryForUpdateList
                                //										.get(0);
                                for(TurnkeyMessageLog msgLog:queryForUpdateList){
                                    msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                                    TurnkeyMessageLogService.INSTANCE
                                    .updMessageLogBySeqSubseq(msgLog);

                                    TurnkeyException e = new TurnkeyException(
                                            TurnkeyUtil
                                            .getProcessResultMessage(info));
                                    TurnkeyUtil
                                    .insertSysEvent(
                                            methodName,
                                            null,
                                            msgLog.getSeqno(),
                                            msgLog.getSubseqno(),
                                            e,
                                            TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                            .getValue(), this
                                            .getClass().getName(),
                                            this.getClass().getPackage()
                                            .getName(), "Sys021",
                                            info.getCode() + " ; "
                                            + info.getDescription());
                                }
                            }
                        }
                    }
                }
                queryList = TurnkeyMessageLogService.INSTANCE
                .queryMessageLog(messageLog);
                List<TurnkeyMessageLogDetail> detailList = new ArrayList<TurnkeyMessageLogDetail>();
                for (TurnkeyMessageLog msgLog : queryList) {
                    TurnkeyMessageLogDetail msgLogDetail = new TurnkeyMessageLogDetail();
                    msgLogDetail.setProcessDts(GatewayUtil.getDateTime());
                    msgLogDetail.setSeqno(msgLog.getSeqno());
                    msgLogDetail.setSubseqno(msgLog.getSubseqno());
                    msgLogDetail.setTask(TaskEnum.Unpack.getValue());
                    msgLogDetail.setFilename(procPackInfo.getBakPath()
                            + File.separator + fileName);
                    if (TurnkeyConstant.STATUS_CONFIRM.equals(msgLog
                            .getStatus()))
                        msgLogDetail.setStatus(TurnkeyConstant.STATUS_SUCCESS);
                    else
                        msgLogDetail.setStatus(msgLog.getStatus());

                    detailList.add(msgLogDetail);
                }
                if (!TurnkeyMessageLogService.INSTANCE
                        .insertMessageLogDetailList(detailList)) {
                    logger.error(
                            "Insert record to TurnkeyMessageDetail for ProcessResult file:"
                            + fileName + " fail!", methodName);
                    TurnkeyException t = new TurnkeyException(
                            "Insert record to TurnkeyMessageDetail for ProcessResult file:"
                            + fileName + " fail!" + fileName);
                    TurnkeyUtil.insertSysEvent(methodName, null, null, t,
                            TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                            .getValue(), this.getClass().getName(),
                            this.getClass().getPackage().getName(), "Sys006");
                }
            } else {
                // 20111019新增ProcessResult新流程-在uuid不存在或是只存在一筆MsgLog且identifier為空(由ReceiveFile新增)執行
                MessageIdentifier mi = new MessageIdentifier();
                if (queryList == null || queryList.size() == 0)// 若UUID不存在
                    // 則新增一筆MsgLog
                {
                    TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
                    msgLog.setInOutBound(TurnkeyConstant.OUTBOUND);
                    msgLog.setSeqno(TurnkeySequenceService.INSTANCE
                            .getNextSequence());
                    msgLog.setSubseqno(mi.getMessageSubId(1));
                    msgLog.setUuid(uuid);
                    msgLog.setMessageType(fileNameInfo[1]);
                    msgLog.setMessageDts(msgDts);
                    msgLog.setStatus(TurnkeyConstant.STATUS_SUCCESS);
                    TurnkeyMessageLogService.INSTANCE.insUpdMessageLog(msgLog);
                    if (queryList == null)
                        queryList = new ArrayList<TurnkeyMessageLog>();
                    queryList.add(msgLog);
                }

                if (processResult.getResult().getInfo().size() == 1) {
                    com.tradevan.gateway.einv.msg.commBean.ProcessResultBody.Info info = processResult
                    .getResult().getInfo().get(0);
                    if (!GenericValidator.isBlankOrNull(info.getCode())) {
                        if (info.getCode().equals(
                                TurnkeyConstant.PROCESS_SUCCESS)) {// 中心端回報成功
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_CONFIRM);
                        } else if (info.getCode().equals(
                                ValidateConstant.ENVELOPE_UNMARSHAL_FAIL)// 整個封套有誤
                                || info.getCode().equals(
                                        TurnkeyConstant.SIGN_ERROR_CODE)) {
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_ERROR);
                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));
                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    uuid,
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                        } else if (Arrays
                                .asList(TurnkeyConstant.FTP_ERROR_CODE)
                                .contains(info.getCode())) {
                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_ERROR);
                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));
                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    uuid,
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                        } else {

                            TurnkeyMessageLogService.INSTANCE
                            .updateStatusMessageLogByUUID(uuid, msgDts,
                                    TurnkeyConstant.OUTBOUND,
                                    TurnkeyConstant.STATUS_ERROR);

                            String messageID = processResult
                            .getMessageInfoType().getMessageType()
                            + processResult.getResult().getInfo()
                            .get(0).getParameter0()
                            + processResult.getResult().getInfo()
                            .get(0).getParameter1();
                            TurnkeyMessageLog msgLog = queryList.get(0);
                            msgLog.setInvoiceIdentifier(messageID);
                            msgLog.setCategoryType(CategoryType
                                    .getCategoryType(processResult
                                            .getMessageInfoType().getAction()));
                            // msgLog.setSubseqno(mi.getMessageSubId(1));
                            msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                            TurnkeyMessageLogService.INSTANCE
                            .insUpdMessageLog(msgLog);
                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));
                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    msgLog.getSeqno(),
                                    msgLog.getSubseqno(),
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                            TurnkeyMessageLogDetail msgDtl = new TurnkeyMessageLogDetail();
                            msgDtl.setSeqno(msgLog.getSeqno());
                            msgDtl.setSubseqno(msgLog.getSubseqno());
                            msgDtl.setTask(TaskEnum.Unpack.getValue());
                            msgDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
                            msgDtl.setProcessDts(GatewayUtil.getDateTime());
                            TurnkeyMessageLogDetailService.INSTANCE
                            .insUpdMessageLogDtl(msgDtl);

                        }
                    }
                } else {
                    TurnkeyMessageLogService.INSTANCE
                    .updateStatusMessageLogByUUID(uuid, msgDts,
                            TurnkeyConstant.OUTBOUND,
                            TurnkeyConstant.STATUS_ERROR);
                    TurnkeyMessageLog oriMsgLog = queryList.get(0);

                    for (int i = 0; i < processResult.getResult().getInfo()
                    .size(); i++) {
                        com.tradevan.gateway.einv.msg.commBean.ProcessResultBody.Info info = processResult
                        .getResult().getInfo().get(i);
                        if (info != null) {
                            String messageID = processResult
                            .getMessageInfoType().getMessageType()
                            + info.getParameter0()
                            + info.getParameter1();

                            TurnkeyMessageLog msgLog = new TurnkeyMessageLog();
                            msgLog.setSeqno(oriMsgLog.getSeqno());
                            msgLog.setSubseqno(mi.getMessageSubId(i + 1));
                            msgLog.setUuid(uuid);
                            msgLog.setMessageType(fileNameInfo[1]);
                            msgLog.setMessageDts(msgDts);
                            msgLog.setStatus(TurnkeyConstant.STATUS_ERROR);
                            msgLog.setInOutBound(TurnkeyConstant.OUTBOUND);
                            msgLog.setInvoiceIdentifier(messageID);
                            msgLog.setCategoryType(CategoryType
                                    .getCategoryType(processResult
                                            .getMessageInfoType().getAction()));
                            TurnkeyMessageLogService.INSTANCE
                            .insUpdMessageLog(msgLog);
                            TurnkeyMessageLogDetail msgDtl = new TurnkeyMessageLogDetail();
                            msgDtl.setSeqno(msgLog.getSeqno());
                            msgDtl.setSubseqno(msgLog.getSubseqno());
                            msgDtl.setTask(TaskEnum.Unpack.getValue());
                            msgDtl.setStatus(TurnkeyConstant.STATUS_ERROR);
                            msgDtl.setProcessDts(GatewayUtil.getDateTime());
                            TurnkeyMessageLogDetailService.INSTANCE
                            .insUpdMessageLogDtl(msgDtl);

                            TurnkeyException e = new TurnkeyException(
                                    TurnkeyUtil.getProcessResultMessage(info));

                            TurnkeyUtil
                            .insertSysEvent(
                                    methodName,
                                    null,
                                    msgLog.getSeqno(),
                                    msgLog.getSubseqno(),
                                    e,
                                    TurnkeyConstant.ErrorCodeEnum.PROCESS_RESULT
                                    .getValue(), this
                                    .getClass().getName(), this
                                    .getClass().getPackage()
                                    .getName(), "Sys021", info
                                    .getCode()
                                    + " ; "
                                    + info.getDescription());
                        }
                    }
                }

                // logger.showConsoleError(TASK,
                // TurnkeyUtil.getMessage("UTL_M0053"), methodName);
                // TurnkeyException t = new TurnkeyException("uuid no found!");
                // TurnkeyUtil.insertSysEvent(methodName, null, uuid, t,
                // TurnkeyConstant.ErrorCodeEnum.UUID_NOT_FOUNE.getValue(),
                // this.getClass().getName(), this
                // .getClass().getPackage().getName(), "Sys018");
                // throw t;
            }
        } catch (XdaoException t) {
            logger.showConsoleError_Xdao(TASK, t, methodName);
            logger.error("XdaoException: " + t.getMessage(), t, methodName);
            try {
                TurnkeyUtil.chkDBConnectionReset(t);
            } catch (XdaoException e) {
                throw e;
            }
            TurnkeyUtil.insertSysEvent(methodName, null, null, null, t,
                    TurnkeyConstant.ErrorCodeEnum.DB.getValue(), this
                    .getClass().getName(), this.getClass().getPackage()
                    .getName(), "Sys006");

            throw t;
        } catch (TurnkeyException t) {
            logger.error("TurnkeyException: " + t.getMessage(), t, methodName);
            throw t;
        }
    }

}
