package nc.net.servlet;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nc.bcmanage.bs.IBusiCenterManageService;
import nc.bs.framework.adaptor.IHttpServletAdaptor;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.comn.NetStreamContext;
import nc.bs.framework.server.ISecurityTokenCallback;
import nc.itf.ws.esb.IEsbDAO;
import nc.pub.sap.constant.SapConstants;
import nc.pubitf.para.SysInitQuery;
import nc.vo.esb.EsbInfoVO;
import nc.vo.esb.EsbVO;
import nc.vo.esb.QueryInfoVO;
import nc.vo.esb.ResultEsbVO;
import nc.vo.esb.ResultVO;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.ws.esb.CertificateVO;
import nc.vo.ws.esb.EsbinfoVO;

/**
 * 对接ESB 包装Servlet类
 * @author 黄旭霖 2018-09-28
 *
 */
public abstract class SapToNcEsbJsonServlet implements IHttpServletAdaptor {
	
	/**
	 * 交互时间精确到毫秒
	 */
	public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
	
	private static IEsbDAO service;
	
	
	private String beginDateStr;
	
	@Override
	public void doAction(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		beginDateStr=dateFormat.format(Calendar.getInstance().getTime());//请求处理开始时间
		initInvocationInfo();
		if(checkEsbkey(request)){//验证通过处理
			
			execFunction(request,response);
			
		}else{//验证失败处理
			ResultVO result=new ResultVO();
			result.setCode(IReturnStatus.FAILING);//失败
			String esbkey=request.getHeader("esbkey");
			if(esbkey==null){
				result.setMessage("esbkey为空，授权验证失败!");
			}else{
				result.setMessage("esbkey授权验证失败!请检擦["+esbkey+"]是否为已认证key值!");
			}
			ResultEsbVO<ResultVO> esb=new ResultEsbVO<ResultVO>();//创建响应对象
			createResultEsbVO(esb);//初始化响应对象
			esb.getEsbInfo().setReturnStatus(IReturnStatus.ESB_FAILING);
			esb.setResultInfo(result);
			sendResponse(response,esb);
		}
	}
	
	/**
	 * 验证esbkey
	 * @param request 
	 * @return true(验证通过)/false(验证失败)
	 */
	private boolean checkEsbkey(final HttpServletRequest request){
		boolean isok=true;
//    	try{
//    		String pathinfo=request.getPathInfo();
//    		if(pathinfo!=null){
//    			pathinfo=pathinfo.substring(1, pathinfo.length());
//    			EsbinfoVO[] esbinfos=(EsbinfoVO[]) getService().findESB("interfacename='"+pathinfo+"'");
//    			if(esbinfos!=null && esbinfos.length>0){
//    				String esbkey=request.getHeader("esbkey");
//    				for(EsbinfoVO esb:esbinfos){
//    					if(esb.getIsstart()!=null && "1".equals(esb.getIsstart())){//检擦是否启用
//	    					CertificateVO typevo=getService().findByPkCode(esb.getCertificate());
//	    					if(typevo==null||!typevo.getEsbkey().equals(esbkey)){
//	    						isok=false;
//	    						break;
//	    					}
//    					}else{
//    						isok=false;
//    						break;
//    					}
//    				}
//    			}else{
//    				isok=false;
//    			}
//    		}
//    	}catch(Exception e){
//    		isok=false;
//    	}
    	return isok;
	}
	
	
	/**
	 * 发送响应信息
	 * @param response
	 * @param esb
	 */
	public void sendResponse(final HttpServletResponse response,ResultEsbVO esb){
		String jsondata=com.alibaba.fastjson.JSONObject.toJSONString(esb);
		PrintWriter out=null;
		try {
			response.setHeader("Content-type", "application/json;charset=UTF-8");
			out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(),"UTF-8"));
	        out.write(jsondata);
	        out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(out!=null){
				out.close();
			}
		}
	}
	
	/**
	 * ESB 逻辑处理接口
	 * @return
	 */
	private static IEsbDAO getService(){
    	if(service==null)
    		service=NCLocator.getInstance().lookup(IEsbDAO.class);
    	return service;
	}
	
	/**
	 * 创建ESB交互对象
	 * @param newi
	 * @param esb 交互VO
	 * @return newi=0(请求对象)
	 */
	public void createEsbVO(final EsbVO esb){
		EsbInfoVO esbInfo=new EsbInfoVO();
		QueryInfoVO queryInfo=new QueryInfoVO();
		Date date=Calendar.getInstance().getTime();//获取当前时间
		//设置请求时间
		esbInfo.setRequestTime(dateFormat.format(date));
		esbInfo.setInstId(getStringUUID());//使用UUID作为流水号
		esb.setEsbInfo(esbInfo);
		esb.setQueryInfo(queryInfo);
	}
	/**
	 * 生成ESB响应对象
	 * @param esb
	 */
	public void createResultEsbVO(final ResultEsbVO esb){
		EsbInfoVO esbInfo=new EsbInfoVO();
		QueryInfoVO queryInfo=new QueryInfoVO();
		Date date=Calendar.getInstance().getTime();//获取当前时间
		//设置响应时间
		esbInfo.setInstId(getStringUUID());//使用UUID作为流水号
		esbInfo.setRequestTime(getBeginDateStr());//设置请求开始时间
		esbInfo.setResponseTime(dateFormat.format(date));//设置响应时间
		esbInfo.setReturnStatus(IReturnStatus.ESB_SUCCEED);//默认响应成功
		esbInfo.setReturnCode(IReturnStatus.ESB_SUCCEED_CODE);//默认成功code
		esbInfo.setReturnMsg("成功");//默认响应成功提示
		esb.setEsbInfo(esbInfo);
		esb.setQueryInfo(queryInfo);
	}
	
	/**
	 * 获得UUID值
	 */
	public static String getStringUUID(){
		return UUID.randomUUID().toString();
	}
	
	/**
	 * @param e	异常
	 * return 异常详细信息
	 */
	public String getExceptionDetail(Exception e) {  
		if(e==null)
			return null;
        StringBuffer stringBuffer = new StringBuffer(e.toString() + "\n");  
        if(e.getStackTrace()==null || e.getStackTrace().length==0)
        	return stringBuffer.toString();  
        StackTraceElement[] messages = e.getStackTrace();  
        int length = messages.length;  
        for (int i = 0; i < length; i++) {
            stringBuffer.append("\t"+messages[i].toString()+"\n");  
        }  
        return stringBuffer.toString();  
    }
	
	/**
	 * 请求处理开始时间
	 * @return
	 */
	public String getBeginDateStr(){
		return beginDateStr;
	}
	
	
	/**
	 * 业务逻辑执行函数
	 * @param request
	 * @param response
	 */
	public abstract void execFunction(HttpServletRequest request, HttpServletResponse response);
	
	private void initInvocationInfo() {
		NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(), "pfxx".getBytes());
		try {
			IBusiCenterManageService busiCenterManageService=NCLocator.getInstance().lookup(IBusiCenterManageService.class);
			InvocationInfoProxy.getInstance().setUserDataSource(busiCenterManageService.getAvailableBusiCenterDsNames()[0]);
			InvocationInfoProxy.getInstance().setGroupId(SysInitQuery.getParaString("GLOBLE00000000000000", "GROUP"));
			InvocationInfoProxy.getInstance().setUserId(SysInitQuery.getParaString("GLOBLE00000000000000", "ITFUSER"));
			/*
			 * ISecurityTokenCallback tc = NCLocator.getInstance().lookup(
			 * ISecurityTokenCallback.class); byte[] token = tc.token("__system".getBytes(),
			 * "NC".getBytes()); NetStreamContext.setToken(token);
			 */
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException("初始化环境变量出错："+e.getMessage());
		}
	}
}
