package com.zi.mwms.solution.event.query;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.orm.SqlCursorItemReader;
import com.cim.idm.framework.util.time.TimeUtils;
import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.wmsextend.generic.master.ConstantMap;

@Service
public class QueryServiceImpl {
	private static Log log = LogFactory.getLog(QueryServiceImpl.class);

	@Autowired
	@Qualifier("ntConstantMap")
	private ConstantMap constantMap;

	
	/*
	* Name : getQueryResult
	* Desc : This function is getQueryResult
	* Author : AIM Systems, Inc
	* Date : 2013.01.03
	*/
	public String getQueryResult(String messageName,
			                     String sourceSubject,
			                     String targetSubject,
			                     String transactionId,
			                     String queryId, String version, Element bindElement) 
		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);
		}

		String usrSql = "SELECT queryString FROM BS_CustomQuery WHERE queryId = ? and version = ? ";

		String[] args = new String[] { queryId, version };

		List<Map<String,Object>> resultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(usrSql, args);

		if (resultList.size() == 0)
			throw new CustomException("CanNotFoundQueryID", queryId, version);

		Map<String,Object> queryMap = resultList.get(0);
		String dbSql = queryMap.get("queryString").toString();
	
		resultList.clear();
	
		String result = "";
		if(StringUtils.indexOf(dbSql, "?") != -1){
			Object[] bind = getBindObjectByElement(bindElement);
			
			if (bind != null){
				log.debug(">> SQL = [" + dbSql + "] : [" + bind.toString() + "]");
			    log.info(">> BIND INFO : [" + bind.toString() + "]");
			}
			else
				log.debug(">> SQL = [" + dbSql + "] : []");
			
			SqlCursorItemReader reader = IDMFrameServiceProxy.getSqlTemplate().queryByCursor(dbSql, bind);						
			try {
				result = QueryServiceUtil.createXmlByList(reader, messageName, sourceSubject,
																  targetSubject, transactionId, queryId, version);
			} catch (Exception e) {
				log.error(e);
			}
		} else {
			try {
				Map<String, String> bindMap = getBindMapByElement(bindElement);
				
				if (bindMap != null){
					log.debug(">> SQL = [" + dbSql + "] : [" + bindMap.toString() + "]");
					log.info(">> BIND INFO : [" + bindMap.toString() + "]");
				}
				else
					log.debug(">> SQL = [" + dbSql + "] : []");
								
				List<Map<String, Object>> sqlResult = 
					IDMFrameServiceProxy.getSqlTemplate().queryForList(dbSql, bindMap);

				result = QueryServiceUtil.createXmlByListName( sqlResult, messageName, sourceSubject,
						targetSubject, transactionId, queryId, version); //new QueryServiceProxy().createXml(resultList, queryID);

				log.info("QueryID: " + queryId + ", Version: " + version + ", QueryResult: " + sqlResult.size());
			} catch (Exception e) {
				log.error(e);
			}
		}


		try
		{
			usrSql = "UPDATE BS_CustomQuery SET USEFLAG = ?, LASTUSETIMEKEY = ? WHERE QUERYID = ? AND VERSION = ? ";
			Object[] useFlagArgs = new String[] { constantMap.FLAG_Y, new TimeUtils().getCurrentEventTimeKey(), queryId, version };
			IDMFrameServiceProxy.getSqlTemplate().update(usrSql, useFlagArgs);
		}
		catch (Exception e) 
		{
			log.error(e);
		}
		
		
		return result;
	}

	/*
	* Name : getBindObjectByElement
	* Desc : This function is getBindObjectByElement
	* Author : AIM Systems, Inc
	* Date : 2013.01.03
	*/
	private Object[] getBindObjectByElement(Element bindElement){
		List<Object> returnBindObject = new ArrayList<Object>();
		if(bindElement == null)
			return null;
		List<Element> bindElementList = bindElement.getChildren();
		for(int i = 0;i < bindElementList.size(); i++){
			returnBindObject.add(bindElementList.get(i).getText());
		}		
		return returnBindObject.toArray();
	}

	/*
	* Name : getBindMapByElement
	* Desc : This function is getBindMapByElement
	* Author : AIM Systems, Inc
	* Date : 2013.01.03
	*/
	private Map getBindMapByElement(Element bindElement){
		Map<String, String> returnBindMap = new HashMap<String, String>();
		if(bindElement == null)
			return null;
		List<Element> bindElementList = bindElement.getChildren();
		for(int i = 0;i < bindElementList.size(); i++){
			returnBindMap.put(bindElementList.get(i).getName(), bindElementList.get(i).getText());
		}
		return returnBindMap;
	}
}