/*
 ****************************************************************************
 *
 *  (c) Copyright 2013 BIDM System. All rights reserved.
 *
 *  This software is proprietary to and embodies the confidential
 *  technology of BIDM System. Possession, use, or copying of this
 *  software and media is authorized only pursuant to a valid written
 *  license from BIDM System.
 *
 ****************************************************************************
 */

package com.cim.idm.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cim.idm.framework.orm.SqlCursorItemReader;
import com.cim.idm.framework.util.sys.SystemPropHelper;
import com.cim.idm.wmsextend.generic.util.SMessageUtil;

/*
 ****************************************************************************
 *  PACKAGE : com.cim.idm.mesextend.query.service
 *  NAME    : QueryServiceProxy.java
 *  TYPE    : JAVA
 *  DESCRIPTION :
 *
 ****************************************************************************
 */

public class ClientServiceUtil
{
    private static Log log = LogFactory.getLog(ClientServiceUtil.class);

    /*
     * Name : createXmlByList
     * Desc : This function is createXmlByList
     * Author : AIM Systems, Inc
     * Date : 2013.01.03
     */
    public static String createXmlByList(SqlCursorItemReader reader, String messageName,
                                         String sourceSubject,
                                         String targetSubject,
                                         String transactionId,
                                         String queryID, String version) throws Exception {

        if(log.isInfoEnabled()){
            log.debug("messageName = " + messageName);
            log.debug("sourceSubject = " + sourceSubject);
            log.debug("targetSubject = " + targetSubject);
            log.debug("transactionId = " + transactionId);
            log.debug("queryId = " + queryID);
            log.debug("version = " + version);
        }

        StringBuilder sXmlMsg = new StringBuilder(50000);

        sXmlMsg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ").append(SystemPropHelper.CR);
        sXmlMsg.append("  <Message>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <MESSAGENAME>").append(messageName).append("</MESSAGENAME>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <SOURCESUBJECT>").append(sourceSubject).append("</SOURCESUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TARGETSUBJECT>").append(targetSubject).append("</TARGETSUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TRANSACTIONID>").append(transactionId).append("</TRANSACTIONID>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <QUERYID>").append(queryID).append("</QUERYID>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <VERSION>").append(version).append("</VERSION>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <DATALIST>").append(SystemPropHelper.CR);
        reader.open();
        int dataSize = 0;
        reader.setListMapper();
        reader.setAppendSpace("          ");
        while(true)
        {
            try {
                Map<String,Object> orderMap = (Map<String, Object>) reader.read();
                if (orderMap == null) break;

                dataSize++;
                sXmlMsg.append("        <DATA>").append(SystemPropHelper.CR);
                orderMap.forEach((k,v)->{
                    String Key = (String) k;
                    String value = null;
                    if (v == null) {
                        value = "";
                    } else if (v instanceof String){
                        value = (String) v;
                    }else{
                        value = v.toString();
                    }
                    sXmlMsg.append("          <").append(Key.toUpperCase()).append(">").append(value).append("</").append(Key.toUpperCase()).append(">").append(SystemPropHelper.CR);
                });

                sXmlMsg.append("        </DATA>").append(SystemPropHelper.CR);
                orderMap.clear();
            } catch (Exception e) {
                log.error(e);
                break;
            }
        }
        reader.close();
        sXmlMsg.append("      </DATALIST>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ReturnCode).append(">").append("0").append("</").append(SMessageUtil.Result_ReturnCode).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ErrorMessage).append(">").append("</").append(SMessageUtil.Result_ErrorMessage).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("  </Message>").append(SystemPropHelper.CR);
        log.info(">> Create Message : " + dataSize);
        log.info("After - createXml");
        return sXmlMsg.toString();
    }

    /*
     * Name : createXmlByListName
     * Desc : This function is createXmlByListName
     * Author : AIM Systems, Inc
     * Date : 2013.01.03
     */
    public static String createXmlByListName(List<Map<String, Object>> sqlResult, String messageName,
                                             String sourceSubject,
                                             String targetSubject,
                                             String transactionId,
                                             String queryID, String version) throws Exception {

        if(log.isInfoEnabled()){
            log.debug("messageName = " + messageName);
            log.debug("sourceSubject = " + sourceSubject);
            log.debug("targetSubject = " + targetSubject);
            log.debug("transactionId = " + transactionId);
            log.debug("queryId = " + queryID);
            log.debug("version = " + version);
        }

        StringBuilder sXmlMsg = new StringBuilder(50000);

        sXmlMsg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ").append(SystemPropHelper.CR);
        sXmlMsg.append("  <Message>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <MESSAGENAME>").append(messageName).append("</MESSAGENAME>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <SOURCESUBJECT>").append(sourceSubject).append("</SOURCESUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TARGETSUBJECT>").append(targetSubject).append("</TARGETSUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TRANSACTIONID>").append(transactionId).append("</TRANSACTIONID>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <QUERYID>").append(queryID).append("</QUERYID>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <VERSION>").append(version).append("</VERSION>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <DATALIST>").append(SystemPropHelper.CR);

        int dataSize = 0;

        for(int i = 0;i < sqlResult.size(); i++)
        {
            Map<String, Object> orderMap = sqlResult.get(i);
            try {
                dataSize++;
                sXmlMsg.append("        <DATA>").append(SystemPropHelper.CR);
                orderMap.forEach((k,v)->{
                    String Key = (String) k;
                    String value = null;
                    if (v == null)
                    {
                        value = "";
                    }
                    else if (v instanceof String){
                        value = (String) v;
                    }else{
                        value = String.valueOf(v);
                    }

                    if(value.indexOf("<?xml version") >= 0)
                    {
                        sXmlMsg.append("          <").append(Key.toUpperCase()).append(">").append("<![CDATA[").append(value).append("]]>").append("</").append(Key.toUpperCase()).append(">").append(SystemPropHelper.CR);
                    }
                    else
                    {
                        if(value.indexOf("<?xml version")==-1)
                        {//if the value is xml string, do not do replaceIllegalCharacter
                            value = replaceIllegalCharacter(value); //add by lvmingtao 2013.04.27
                        }

                        sXmlMsg.append("          <").append(Key.toUpperCase()).append(">").append(value).append("</").append(Key.toUpperCase()).append(">").append(SystemPropHelper.CR);
                    }
                });

                sXmlMsg.append("        </DATA>").append(SystemPropHelper.CR);
            } catch (Exception e) {
                log.error(e);
                break;
            }
        }

        sXmlMsg.append("      </DATALIST>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ReturnCode).append(">").append("0").append("</").append(SMessageUtil.Result_ReturnCode).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ErrorMessage).append(">").append("</").append(SMessageUtil.Result_ErrorMessage).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("  </Message>").append(SystemPropHelper.CR);
        log.info(">> Create Message : " + dataSize);
        log.info("After - createXml");
//		System.out.println(sXmlMsg.toString());
        return sXmlMsg.toString();
    }

    /*
     * Name : createXmlByListName
     * Desc : This function is createXmlByListName
     * Author : AIM Systems, Inc
     * Date : 2013.01.03
     */
    public static String createXmlByListName(String messageName,
                                             String sourceSubject,
                                             String targetSubject,
                                             String transactionId,
                                             String queryID, String version) throws Exception {

        if(log.isInfoEnabled()){
            log.debug("messageName = " + messageName);
            log.debug("sourceSubject = " + sourceSubject);
            log.debug("targetSubject = " + targetSubject);
            log.debug("transactionId = " + transactionId);
            log.debug("queryId = " + queryID);
            log.debug("version = " + version);
        }

        StringBuilder sXmlMsg = new StringBuilder(50000);

        sXmlMsg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ").append(SystemPropHelper.CR);
        sXmlMsg.append("  <Message>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <MESSAGENAME>").append(messageName).append("</MESSAGENAME>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <SOURCESUBJECT>").append(sourceSubject).append("</SOURCESUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TARGETSUBJECT>").append(targetSubject).append("</TARGETSUBJECT>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <TRANSACTIONID>").append(transactionId).append("</TRANSACTIONID>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Header>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <QUERYID>").append(queryID).append("</QUERYID>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <VERSION>").append(version).append("</VERSION>").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Body>").append(SystemPropHelper.CR);
        sXmlMsg.append("    <Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ReturnCode).append(">").append("0").append("</").append(SMessageUtil.Result_ReturnCode).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("      <").append(SMessageUtil.Result_ErrorMessage).append(">").append("</").append(SMessageUtil.Result_ErrorMessage).append(">").append(SystemPropHelper.CR);
        sXmlMsg.append("    </Return>").append(SystemPropHelper.CR);
        sXmlMsg.append("  </Message>").append(SystemPropHelper.CR);
//		System.out.println(sXmlMsg.toString());
        return sXmlMsg.toString();
    }

    /*
     * @author lvmingtao
     * input string : value
     * return a string replace & < > use &amp; &lt; &gt;
     */
    private static String replaceIllegalCharacter(String value) {
        String str = value.replace("&", "&amp;");
        str = str.replace("<", "&lt;");
        str = str.replace(">", "&gt;");
        return str;
    }

    /*
     * Name : createStringByList
     * Desc : This function is createStringByList
     * Author : AIM Systems, Inc
     * Date : 2013.01.03
     */
    public static String createStringByList(SqlCursorItemReader reader, String messageName,
                                            String sourceSubject,
                                            String targetSubject,
                                            String transactionId,
                                            String queryID, String version) throws Exception {

        if(log.isInfoEnabled()){
            log.debug("messageName = " + messageName);
            log.debug("sourceSubject = " + sourceSubject);
            log.debug("targetSubject = " + targetSubject);
            log.debug("transactionId = " + transactionId);
            log.debug("queryId = " + queryID);
            log.debug("version = " + version);
        }

        StringBuilder sStrMsg = new StringBuilder(50000);

        sStrMsg.append(messageName).append(".REP ");
        sStrMsg.append("HDR(").append(sourceSubject).append(",").append(targetSubject);
        sStrMsg.append(",").append(transactionId).append(") ");
        sStrMsg.append("QUERYID=").append(queryID).append(" ");
        sStrMsg.append("VERSION=").append(version).append(" ");
        sStrMsg.append("DATA=\"");

        reader.open();
        //int dataSize = 0;
        reader.setListMapper();
        reader.setAppendSpace("          ");
        while(true)
        {
            try {
                Map<String,Object> orderMap = (Map<String,Object>)reader.read();
                if (orderMap == null) break;
                orderMap.forEach((k,v)->{
                    String value = null;
                    if (v == null) {
                        value = "";
                    } else if (v instanceof String)
                        value = (String) v;
                    else
                        value = v.toString();
                    sStrMsg.append(value);
                    sStrMsg.append(" ");
                });
                sStrMsg.append(SystemPropHelper.CR);
                orderMap.clear();
            } catch (Exception e) {
                log.error(e);
                break;
            }
        }
        sStrMsg.append("\"");
        reader.close();
        return sStrMsg.toString();
    }

    public static List<Map<String, Object>> createMapByList(SqlCursorItemReader reader, String queryID, String version)
            throws Exception {
        List<Map<String, Object>> queryResult = new ArrayList<Map<String, Object>>();
        reader.open();
        int dataSize = 0;
        reader.setListMapper();
        reader.setAppendSpace("          ");
        while (true) {
            try {
                Map<String, Object> orderMap = (Map<String, Object>) reader.read();
                if (orderMap == null)
                    break;

                dataSize++;
                orderMap.forEach((k, v) -> {
                    String Key = (String) k.toUpperCase();
                    String value = null;
                    if (v == null) {
                        value = "";
                    } else if (v instanceof String) {
                        value = v.toString().toUpperCase();
                    } else {
                        value = v.toString().toUpperCase();
                    }
                    Map<String, Object> tempMap = new HashMap<String, Object>();
                    tempMap.put(Key, value);
                    queryResult.add(tempMap);
                });
                orderMap.clear();
            } catch (Exception e) {
                log.error(e);
                break;
            }
        }
        reader.close();
        log.info(">> Create Message : " + dataSize);
        log.info("After - createXml");
        return queryResult;
    }

}
