package com.duiba.tuia.youtui.web.tool;

import com.duiba.tuia.youtui.web.constant.Constants;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.duiba.tuia.youtui.web.exception.ActivityRuntimeException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
 * ClassName: AjaxUtils <br/>
 * date: 2016年7月13日 上午9:44:26 <br/>
 *
 * @author zp
 * @version 
 * @since JDK 1.6
 */
public class AjaxUtils {
	    //-- header 常量定义 --//
		private static final String HEADER_ENCODING = "encoding";
		private static final String HEADER_NOCACHE = "no-cache";
		private static final String DEFAULT_ENCODING = "UTF-8";
		private static final boolean DEFAULT_NOCACHE = true;

		public static final ObjectMapper mapper = JsonUtils.mapper;

		static{
			mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		}
		
		private AjaxUtils() {}

		/**
		 * 
		 * render:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出内容的简便函数.
         * render("text/plain", "hello", "encoding:GBK");
         * render("text/plain", "hello", "no-cache:false");
         * render("text/plain", "hello", "encoding:GBK", "no-cache:false");
		 * @param response
		 * @param contentType
		 * @param content
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void render(HttpServletResponse response,final String contentType, final String content, final String... headers) {
			initResponseHeader(response,contentType, headers);
			PrintWriter write =null;
			try {
				write = response.getWriter();
				write.write(content);
				write.flush();
			} catch (IOException e) {
				throw new ActivityRuntimeException(e.getMessage(), e);
			}finally{
				if(write!=null){
					write.close();
				}
			}
		}

		/**
		 * 
		 * renderText:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出文本.
		 * @param response
		 * @param text
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderText(HttpServletResponse response,final String text, final String... headers) {
			render(response, Constants.ContentType.TEXT_TYPE, text, headers);
		}
		
		/**
		 * 
		 * renderHtml:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出HTML.
		 * @param response
		 * @param html
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderHtml(HttpServletResponse response,final String html, final String... headers) {
			render(response, Constants.ContentType.HTML_TYPE, html, headers);
		}

		/**
		 * 
		 * renderXml:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出XML.
		 * @param response
		 * @param xml
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderXml(HttpServletResponse response,final String xml, final String... headers) {
			render(response, Constants.ContentType.XML_TYPE, xml, headers);
		}

		/**
		 * 
		 * renderJson:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出JSON.
		 * @param response
		 * @param jsonString
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderJson(HttpServletResponse response,final String jsonString, final String... headers) {
			render(response, Constants.ContentType.JSON_TYPE, jsonString, headers);
		}

		/**
		 * 
		 * renderJson:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出JSON,使用Jackson转换Java对象.
		 * @param response
		 * @param data
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderJson(HttpServletResponse response,final Object data, final String... headers) {
			initResponseHeader(response, Constants.ContentType.JSON_TYPE, headers);
			try {
				mapper.writeValue(response.getWriter(), data);
			} catch (IOException e) {
				throw new IllegalArgumentException(e);
			}
		}

		/**
		 * 
		 * renderJsonp:(这里用一句话描述这个方法的作用). <br/>
		 * 直接输出支持跨域Mashup的JSONP.
		 * @param response
		 * @param callbackName
		 * @param object
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderJsonp(HttpServletResponse response,final String callbackName, final Object object, final String... headers) {
			String jsonString = null;
			try {
				jsonString = mapper.writeValueAsString(object);
			} catch (IOException e) {
				throw new IllegalArgumentException(e);
			}

			String result = new StringBuilder().append(callbackName).append("(").append(jsonString).append(");").toString();
			render(response, Constants.ContentType.JS_TYPE, result, headers);
		}
		

		/**
		 * 分析并设置contentType与headers.
		 */
		private static void initResponseHeader(HttpServletResponse response, final String contentType, final String... headers) {
			//分析headers参数
			String encoding = DEFAULT_ENCODING;
			boolean noCache = DEFAULT_NOCACHE;
			for (String header : headers) {
				String headerName = StringUtils.substringBefore(header, ":");
				String headerValue = StringUtils.substringAfter(header, ":");

				if (StringUtils.equalsIgnoreCase(headerName, HEADER_ENCODING)) {
					encoding = headerValue;
				} else if (StringUtils.equalsIgnoreCase(headerName, HEADER_NOCACHE)) {
					noCache = Boolean.parseBoolean(headerValue);
				} else {
					throw new IllegalArgumentException(headerName + "不是一个合法的header类型");
				}
			}
			
			//设置headers参数
			String fullContentType = contentType + ";charset=" + encoding;
			response.setContentType(fullContentType);
			if (noCache) {
				setDisableCacheHeader(response);
			}
		}
		
		/**
		 * 
		 * setDisableCacheHeader:(这里用一句话描述这个方法的作用). <br/>
		 * 设置禁止客户端缓存的Header.
		 * @param response
		 * @since JDK 1.6
		 */
		public static void setDisableCacheHeader(HttpServletResponse response) {
			//Http 1.0 header
			response.setDateHeader("Expires", 1L);
			response.addHeader("Pragma", HEADER_NOCACHE);
			//Http 1.1 header
			response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
		}
		
		/**
		 * 
		 * renderJsonporJson:(这里用一句话描述这个方法的作用). <br/>
		 * @param response
		 * @param callbackName
		 * @param object
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderJsonporJson(HttpServletResponse response,final String callbackName, final Object object, final String... headers){
			if (StringUtils.isNotBlank(callbackName))
			{
				renderJsonp(response, callbackName, object, headers);
			}else {
				renderJson(response, object, headers);
			}
		}
		/**
		 * 
		 * renderJsonporJson2:(这里用一句话描述这个方法的作用). <br/>
		 * @param response
		 * @param callbackName
		 * @param data
		 * @param headers
		 * @since JDK 1.6
		 */
		public static void renderJsonporJson2(HttpServletResponse response,final String callbackName, final String data, final String... headers){
			if (StringUtils.isNotBlank(callbackName))
			{

				String result=callbackName+"("+data+")";
				renderText(response, result, headers);
			}else {
				renderJson(response, data, headers);
			}
		}
}
