package utis.wall.common.util;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Class Name  : MainController.java
 * @Description : 메인 Controller 
 * @Modification Information  
 * 
 *  수정일			수정자		수정내용
 *  -------------	---------	-------------------------------
 *  2015. 9. 9.	YJLEE	    최초생성
 * 
 * @author YJLEE
 * @since 2015. 9. 9.
 * @version 1.0
 * @see
 * 
 *  Copyright (C) by LBCSOFT All right reserved.
 */
public class CommonUtil {
	/** Log4j log */
	private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
	
	/**
	 * 파라미터 값 Map으로 변환
	 * @param req
	 * @param isDML
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getParameterMap(HttpServletRequest req) throws Exception {

		// 추출한 파라미터를 저장할 객체
		Map<String, Object> map = new HashMap<String, Object>();
		
		try {
		
			// HttpServletRequest 객체에 있는 파라미터 Key값 추출
			Enumeration<String>     keys   = req.getParameterNames();
			
			while(keys.hasMoreElements()) {
			
				// Key값
				String key     = keys.nextElement();
				
				// 파라미터 Value
				String aVal[]  = req.getParameterValues(key);
				int    aSize   = aVal.length;
				
				// String
				if(aSize == 1) {
					map.put(key, convertXSS(parseString(URLDecoder.decode(aVal[0], "UTF-8"), "")));
				}
				
				// 1개 이상
				else if(aSize > 1) {
				
					// List
					List<String> arrList = new ArrayList<String>();
					
					for(String s : aVal) {
						arrList.add(convertXSS(parseString(s, "")));
					}
					
					map.put(key, arrList);
				}
			}
		} 
		
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return map;
	}
	
	
	/**
	 * XSS Convertor
	 * @param target
	 * @return
	 */
	public static String convertXSS(String target) {
		
		// target문자열이 null이 아닌 경우 실행
		if(target != null) {
			
			// 공백제거
			target = target.trim();
			
			// 문자열 치환
			target = replace(target, "&", "&amp;");
			target = replace(target, "<", "&lt;");
			target = replace(target, ">", "&gt;");
			target = replace(target, "'", "&quot;");
			target = replace(target, "\"", "");
			target = replace(target, "--", "");
			target = replace(target, "{", "&#123;");
			target = replace(target, "}", "&#125;");
			target = replace(target, "\"", "&#34;");
			target = replace(target, ";", "&#59;");
			target = replace(target, "'", "&#39;");
		}
		
		return target;
	}
	
	/**
	 * 문자열 치환
	 * @param str
	 * @param oldString
	 * @param newString
	 * @return
	 */
	public static String replace(String str,String oldString,String newString) {
		int index = 0;
		
		while(str.indexOf(oldString, index) >= 0) {
		
			index  = str.indexOf(oldString, index);
			str    = str.substring(0, index) + newString + str.substring(index + oldString.length());
			index += newString.length();
		}
		
		return str;
	}
	
	public static String parseString(Object obj, String replacement) {

		// 변환해서 return할 값
		String str = "";
		
		try {
		
			if(obj == null) {
				str = replacement;
			} else {
				// String 변환
				String strr = String.valueOf(obj);
			
				if(strr == null) {
					str = replacement;
				} else {
			
					// 공백제거
					String val = strr.trim().toLowerCase();
			
					// 공백이거나 null 텍스트인 경우 대체문자로 대체
					if("".equals(val) || "null".equals(val)) {
						str = replacement;
					}
			
					// 아닌 경우 String 변환객체 return
					else {
						str = strr;
					}
				}
			}
		} catch(Exception ex) {
			// 에러발생시 공백 return
			str = replacement;
		}
		
		return str;
	}
	
	/**
	 * 페이지에서 보낸 파라미터를 추출하여 ModelAndView에 세팅 후 화면이동
	 *   ==> 파라미터가 필요한 화면이동에만 사용
	 * @param req
	 * @param viewName
	 * @return
	 */
	public ModelAndView setPageParam(HttpServletRequest req
			                        ,String             viewName) {
		
		// ModelAndView 객체
		ModelAndView mav = new ModelAndView(viewName);
		
		try {
			
			// HttpServletRequest에 저장되어 있는 파라미터를 추출하여 ModelAndView에 세팅
			Map<String, Object> map = getParameterMap(req);
			
			// HashMap에서 꺼내서 Parameter 추출
			Iterator<String>    it  = map.keySet().iterator();
			
			// 반복문을 돌면서 파라미터 추출 후 ModelAndView에 세팅
			while(it.hasNext()) {
				
				String key = it.next();
				String val = parseString(map.get(key), "");
				
				mav.addObject(key, val);
			}
		}
		
		catch(Exception ex) {
			
			ex.printStackTrace();
		}
		
		return mav;
	}
	
	
	/**
	 * Map형태의 객체에서 Value값 얻기
	 * @param obj
	 * @param key
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static Object getValue(Object obj,String key) {
		
		// return할 객체
		Object objj = null;
		
		try {
			// Map
			if(obj instanceof Map) {
				objj = ((Map)obj).get(key);
			}
			
			// HashMap
			else if(obj instanceof HashMap) {
				objj = ((HashMap)obj).get(key);
			}
			
			// LinkedHashMap
			else if(obj instanceof LinkedHashMap) {
				objj = ((LinkedHashMap)obj).get(key);
			}
			
			// CaseInsensitiveMap
			else if(obj instanceof CaseInsensitiveMap) {
				objj = ((CaseInsensitiveMap)obj).get(key);
			}
			
			// 그 외
			else {
				objj = null;
			}
		} catch(Exception ex) {
			// 에러 발생시 null return
			objj = null;
		}
		
		return objj;
	}
	
	

	/**
	 * int 변환
	 * @param obj
	 * @return
	 */
	public static int parseInt(Object obj) {
		
		// return할 값
		int num = 0;
		
		try {
			
			// double인 경우
			if(obj instanceof Double) {
				
				num = (int)Double.parseDouble(String.valueOf(obj));
			}
			
			// 그 외
			else {

				num = Integer.parseInt(String.valueOf(obj));
			}
		}
		
		catch(Exception ex) {
			
			// 에러발생시 0 return
			num = 0;
		}
		
		return num;
	}
	
	public static String getDeviceType(HttpServletRequest req) {
		Device device = DeviceUtils.getCurrentDevice(req);        
		String deviceType = "unknown";
        
		if (device == null) {
            return deviceType;
        }
		
        if (device.isNormal()) {
            deviceType = "normal";
        } else if (device.isMobile()) {
            deviceType = "mobile";
        } else if (device.isTablet()) {
            deviceType = "tablet";
        }
		
		return deviceType;
	}
}
