package com.udapsoft.modular.web.ibsheet7.util;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import kr.co.hsnc.common.base.WAFLogger;
import kr.co.hsnc.common.sql.RowSet;
import kr.co.hsnc.common.sql.RowSetImpl;
import kr.co.hsnc.common.sql.search.Search;
import kr.co.hsnc.common.sql.search.SearchImpl;
import kr.co.hsnc.common.util.ValueObject;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.springframework.web.bind.ServletRequestUtils;

import com.udapsoft.waf.system.HandlerStorage;

/**
 * Modular WAF IBSheet7 Util 클래스 
 * @author Sunyoup
 *
 */
public class IBSheet7Utils {
	
	public static final String INSERT_STATUS = "I";
	public static final String UPDATE_STATUS = "U";
	public static final String DELETE_STATUS = "D";
	
	public static final String COMBO_SEPARATOR = "|";

	/**
	 * @param doc
	 * @param outputter
	 * @param encoding
	 * @throws IOException
	 */
	public static void printDebugXml(Document doc, XMLOutputter outputter, String encoding) throws IOException {
		Format f = Format.getPrettyFormat();
		f.setEncoding(encoding);
		outputter.setFormat(f);
		StringWriter out = new StringWriter();
		outputter.output(doc, out);
		WAFLogger.debug("IBSheet7 응답 결과 XML은 다음과 같습니다.\n" + out.toString());
	}
	
	/**
	 * @param status
	 * @return
	 */
	public static boolean equalStatusInsert(String status) {
		return (INSERT_STATUS.equals(status));
	}
	
	/**
	 * @param status
	 * @return
	 */
	public static boolean equalStatusUpdate(String status) {
		return (UPDATE_STATUS.equals(status));
	}
	
	/**
	 * @param status
	 * @return
	 */
	public static boolean equalStatusDelete(String status) {
		return (DELETE_STATUS.equals(status));
	}
	
	/**
	 * request parameter중에서 sheet id에 속한 sheet 파라미터를 추출한다.
	 * @param sheetId
	 * @param params
	 * @param paramsArrayIndex
	 * @return
	 * @throws Exception
	 */
	public static ValueObject getIBSheet7SqlParams(String sheetId, ValueObject params, int paramsArrayIndex) throws Exception {
		ValueObject vo = new ValueObject();
		try {
			List<?> keyList = params.getKeys();
			for (int i = 0; i < keyList.size(); i++) {
 				String key = ((String)keyList.get(i));
 				Pattern p = Pattern.compile("\\.");
 			    Matcher m = p.matcher(key);
 			    int count = 0;
 			    for(int j = 0; m.find(j); j = m.end())
 			    	count++;
 				
				if ( key.startsWith(sheetId) && count == 1 ) {
					Object object = null;
					if (params.getObject(key) instanceof String[]) {
						String[] values = (String[]) (params.getObject(key));
						object = values[paramsArrayIndex];
					} else {
						if ("".equals(params.get(key))) {
							object = new String("");
						} else {
							object = params.get(key);
						}
					}
					
					vo.set(key.substring(sheetId.length() + 1, key.length()), object);
				}
			}
			return vo;
			
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
	
	/**
	 * IBSheet7 combo type과 시스템 코드 데이터 연계를 통하여 해당하는 ComboText, ComboCode Attribute 설정
	 * @param systemCode
	 * @return
	 * @throws Exception
	 */
	public static void setIBSheet7Combo(String sheetId, String systemCode, HandlerStorage storage) throws Exception {
		Map<String, String> combo = new HashMap<String, String>();
		try {
			Search search = new SearchImpl();
	        RowSet rowSet = new RowSetImpl();
	        //TODO 시스템 코드 테이블 DAO를 사용하는 방법 추천!(아래는 예제 차원에서 작성된 방법)
        	search.setStatement("select detail_cd, detail_cd_value from test_table where master_cd = ? \n ");
        	search.addParameter(systemCode);
            rowSet = search.execute();
            
            String code = "";
            String text = "";
            for (int i = 0; i < rowSet.size(); i++) {
            	code += rowSet.getRow(i).get("detail_cd") + COMBO_SEPARATOR;
            	text += rowSet.getRow(i).get("detail_cd_value") + COMBO_SEPARATOR;
            }
            
            if (rowSet.size() > 0) {
            	combo.put("CODE", code.substring(0, code.length() - 1));
            	combo.put("TEXT", text.substring(0, text.length() - 1));
            	storage.request.setAttribute(sheetId.toUpperCase() + "_" + systemCode.toUpperCase(), combo);
            }
	            
		} catch (Exception e) {
			throw e;
		}
	}
	
	
	/*시트 에러시 호출 */
	public static Document exceptionHandle(HttpServletRequest request, Throwable ex) {
		Document doc = new Document();
		try {
			Format format = Format.getCompactFormat();
			format.setEncoding("utf-8");
			XMLOutputter outputter = new XMLOutputter();
			outputter.setFormat(format);

			Element root = new Element("SHEET");
			doc.setRootElement(root);

			String commandType = ServletRequestUtils.getStringParameter(request, IBSheet7Constants.COMMAND_TYPE_KEY, IBSheet7Constants.COMMAND_TYPE_SEARCH);
			if (commandType.equals(IBSheet7Constants.COMMAND_TYPE_SEARCH)) {
				Element message = new Element("MESSAGE");
				message.addContent(ex.getMessage());
				root.addContent(message);
				
			} else {
				Element result = new Element("RESULT");
				result.setAttribute("CODE", "-1");
				result.setAttribute("MESSAGE", ex.getMessage());

				root.addContent(result);
			}
			
		} catch (Exception e) {
			WAFLogger.error("Failed to rendering Error Message", e);
		}
		
		return doc;
	}
}
