package com.trs.project.util.hycloud;


import com.trs.project.util.hycloud.eventhandler.ICallbackEventHandler;
import com.trs.project.util.hycloud.eventhandler.ICallbackFailureHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class WCMServiceCaller {

    public final static ICallbackFailureHandler CALLLBACK_FAILURE_HANDLER_DEFAULT = new ICallbackFailureHandler() {
        public void onFailure(Dispatch _dispatch)
                throws Web2frameClientException {
            ResponseBuddy oResponseBuddy = _dispatch.getResponseBuddy();
            if (isTRSNotLogin(oResponseBuddy)) {
                log.info("未登录");
            } else if (isResponse500(oResponseBuddy)) {
                System.out.println(_dispatch.getResponseText());
            } else if (isFailure(oResponseBuddy)) {
                System.out.println("StatusCode:"
                        + oResponseBuddy.getStatusCode() + "\n"
                        + _dispatch.getResponseText());
            }
            _dispatch.setFailure(true);
        }
    };

    public static Dispatch UploadFile(String _sFileName) {
        Dispatch oDispatch = null;
        String sFileExt = _sFileName.substring(_sFileName.lastIndexOf('.') + 1);
        try {
            HttpClientBuddy oHttpClientBuddy = new HttpClientBuddy(
                    ServiceConfig.WCM_SERVICE_CHARSET, new String[][] { {"FileExt", sFileExt } });
            ResponseBuddy oResponseBuddy = null;
            oResponseBuddy = oHttpClientBuddy.updateFile(
                    ServiceConfig.WCM_UPLOAD_FILE_URL,
                    CMyFile.readBytesFromFile(_sFileName));
            oDispatch = new Dispatch(oResponseBuddy);
            try {
                if (isTRSNotLogin(oResponseBuddy) || isFailure(oResponseBuddy)) {
                    CALLLBACK_FAILURE_HANDLER_DEFAULT.onFailure(oDispatch);
                }
            } finally {
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return oDispatch;
    }

    public static Dispatch uploadFile(String _sFileName, String _sTargetFlag) {
        Dispatch oDispatch = null;
        String sFileExt = _sFileName.substring(_sFileName.lastIndexOf('.') + 1);
        try {
            String sTargetFlag = _sTargetFlag;
            if (CMyString.isEmpty(sTargetFlag)) {
                sTargetFlag = "U0";
            }
            HttpClientBuddy oHttpClientBuddy = new HttpClientBuddy(
                    ServiceConfig.WCM_SERVICE_CHARSET, new String[][] {
                            { "FileExt", sFileExt },
                            { "TargetFlag", _sTargetFlag } });
            ResponseBuddy oResponseBuddy = null;
            oResponseBuddy = oHttpClientBuddy.updateFile(
                    ServiceConfig.WCM_UPLOAD_FILE_URL,
                    CMyFile.readBytesFromFile(_sFileName));
            oDispatch = new Dispatch(oResponseBuddy);
            try {
                if (isTRSNotLogin(oResponseBuddy) || isFailure(oResponseBuddy)) {
                    CALLLBACK_FAILURE_HANDLER_DEFAULT.onFailure(oDispatch);
                }
            } finally {
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return oDispatch;
    }

    //-----start---------
    public static Dispatch Call(ServiceObject _oServiceObject, boolean _bPost)
            throws Exception {
        Dispatch oDispatch = null;
        HttpClientBuddy oHttpClientBuddy = new HttpClientBuddy(ServiceConfig.WCM_SERVICE_CHARSET);
        		// 如果是Post方式，需要在头部传入formdata头部信息
        if (_bPost) {
            oHttpClientBuddy = new HttpClientBuddy(
                    ServiceConfig.WCM_SERVICE_CHARSET, new String[][] { //
                            { "formdata", "1" }//
                    });
        }
        ResponseBuddy oResponseBuddy = null;
        String sQueryURL = ServiceConfig.WCM_SERVICE_URL;

        try {
        	if (_bPost) {
				Map hPostData = _oServiceObject.getPostData();
				if(hPostData == null){
					hPostData = new HashMap();
				}
				hPostData.put("serviceid", _oServiceObject.getServiceId());
				hPostData.put("methodname", _oServiceObject.getMethodName());
				oResponseBuddy = oHttpClientBuddy.doPost(sQueryURL,hPostData);
            } else {
                oResponseBuddy = oHttpClientBuddy.doGet(
                        ServiceConfig.WCM_SERVICE_URL, _oServiceObject
                                .toQueryString());
            }
        } catch (HttpClientExcuteException e) {
            throw new Exception(e);
        }

        oDispatch = new Dispatch(oResponseBuddy);
        try {
            if (isTRSNotLogin(oResponseBuddy)) {
                _oServiceObject.onFailure(oDispatch);
            }
            if (isFailure(oResponseBuddy)) {
                _oServiceObject.onFailure(oDispatch);
            } else if (isSuccess(oResponseBuddy)) {
                _oServiceObject.onSuccess(oDispatch);
            }
        } finally {
            _oServiceObject.onComplete(oDispatch);
        }
        return oDispatch;
    }
    //------end--
    
    
    //原有的wcm
    public static Dispatch Call2(ServiceObject _oServiceObject, boolean _bPost) {
        Dispatch oDispatch = null;
        try {
            HttpClientBuddy oHttpClientBuddy = new HttpClientBuddy(
            		ServiceConfigWcm.WCM_SERVICE_CHARSET);
            ResponseBuddy oResponseBuddy = null;
            String sQueryURL = ServiceConfigWcm.WCM_SERVICE_URL;
            String cruser = (String) _oServiceObject.getPostData().get(
                    "CURRUSER");
            if (cruser != null) {
                sQueryURL += ("?CRUSER=" + URLEncoder.encode(cruser, "UTF-8"));
            }

            if (_bPost) {
                oResponseBuddy = oHttpClientBuddy.doPost(sQueryURL,
                        _oServiceObject.toPostXml());
            } else {
                oResponseBuddy = oHttpClientBuddy.doGet(sQueryURL,
                        _oServiceObject.toQueryString());
            }
            oDispatch = new Dispatch(oResponseBuddy);
            try {
                if (isTRSNotLogin(oResponseBuddy)) {
                    _oServiceObject.onFailure(oDispatch);
                }
                if (isFailure(oResponseBuddy)) {
                    _oServiceObject.onFailure(oDispatch);
                } else if (isSuccess(oResponseBuddy)) {
                    _oServiceObject.onSuccess(oDispatch);
                }
            } finally {
                _oServiceObject.onComplete(oDispatch);
            }
        } catch (Exception ex) {
            ex.printStackTrace();

        }
        return oDispatch;
    }

    private static boolean isTRSNotLogin(ResponseBuddy oResponseBuddy) {
        return "true".equalsIgnoreCase(oResponseBuddy.getHeader("TRSNotLogin"));
    }

    /**
     * @param _responseBuddy
     * @return
     */
    private static boolean isFailure(ResponseBuddy _responseBuddy) {
        return isResponse500(_responseBuddy)
                || _responseBuddy.getStatusCode() > 400;
    }

    /**
     * @param _responseBuddy
     * @return
     */
    private static boolean isSuccess(ResponseBuddy _responseBuddy) {
        return _responseBuddy.getStatusCode() == 200
                && !isFailure(_responseBuddy);
    }

    /**
     * @param oResponseBuddy
     * @return
     */
    private static boolean isResponse500(ResponseBuddy oResponseBuddy) {
        return oResponseBuddy.getStatusCode() == 500
                || "true".equalsIgnoreCase(oResponseBuddy
                        .getHeader("TRSException"));
    }

    public static Dispatch Call(String _sServiceId, String _sMethodName,
            Map _oPostData, boolean _bPost) throws Exception {
        ServiceObject oServiceObject = new ServiceObject(_sServiceId,
                _sMethodName);
        oServiceObject.setPostData(_oPostData);
        return WCMServiceCaller.Call(oServiceObject, _bPost);
    }
    
    /**
     * 查询wcm
     * @param _sServiceId
     * @param _sMethodName
     * @param _oPostData
     * @param _bPost
     * @return
     * @throws Exception
     */
    public static Dispatch Call2(String _sServiceId, String _sMethodName,
            Map _oPostData, boolean _bPost) throws Exception {
        ServiceObject oServiceObject = new ServiceObject(_sServiceId,
                _sMethodName);
        oServiceObject.setPostData(_oPostData);
        return WCMServiceCaller.Call2(oServiceObject, _bPost);
    }

    /**
     * ��
     * 
     * @param _sServiceId
     * @param _sMethodName
     * @param _oPostData
     * @param _arrEventHandlers
     * @param _bPost
     * @return
     * @throws Exception 
     */
    public static Dispatch Call(String _sServiceId, String _sMethodName,
            Map _oPostData, ICallbackEventHandler[] _arrEventHandlers,
            boolean _bPost) throws Exception {
        ServiceObject oServiceObject = new ServiceObject(_sServiceId,
                _sMethodName);
        oServiceObject.setPostData(_oPostData);
        oServiceObject.addEventHandlers(_arrEventHandlers);
        return WCMServiceCaller.Call(oServiceObject, _bPost);
    }


    public static Dispatch MultiCall(ServiceObject[] _arrServiceObjects) {
        // TODO
        return null;
    }

    /**
     * JSP����
     * 
     * @param _sUrl
     * @param _oPostData
     * @param _bPost
     * @return
     */
    public static Dispatch JspRequest(String _sUrl, Map _oPostData,
            boolean _bPost) {
        // TODO
        return null;
    }

    /**
     * ����������ת����URL��ʽ��QUERYSTRING����
     * 
     * @param _sServiceId
     * @param _sMethodName
     * @param _mapParams
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String makePostParams(String _sServiceId,
            String _sMethodName, Map _mapParams)
            throws UnsupportedEncodingException {
        StringBuffer sb = new StringBuffer();

        sb.append("serviceid").append("=").append(_sServiceId);
        sb.append("&methodname=").append(_sMethodName);

        if (_mapParams != null && _mapParams.size() > 0) {
            Iterator iterParamNames = _mapParams.keySet().iterator();
            for (; iterParamNames.hasNext();) {
                String paramName = (String) iterParamNames.next();
                if (paramName == null) {
                    continue;
                }
                sb.append("&")
                        .append(paramName)
                        .append("=")
                        .append(URLEncoder.encode(_mapParams.get(paramName)
                                .toString(), "UTF-8"));
            }
        }
        String result = sb.toString();
        sb.setLength(0);

        return result;
    }

    /**
     * ����������ת����xml�ṹ��POST����
     * 
     * @param _sServiceId
     * @param _sMethodName
     * @param _mapParams
     * @return
     */
    public static String makePostData(String _sServiceId, String _sMethodName,
            Map _mapParams) {
        StringBuffer sb = new StringBuffer();
        sb.append("<post-data>");
        sb.append("<method type=\"" + _sMethodName + "\">" + _sServiceId
                + "</method>");
        if (_mapParams != null && _mapParams.size() > 0) {
            sb.append("<parameters>");
            Iterator iterParamNames = _mapParams.keySet().iterator();
            for (; iterParamNames.hasNext();) {
                String paramName = (String) iterParamNames.next();
                if (paramName == null) {
                    continue;
                }
                sb.append("<" + paramName + ">");
                sb.append("<![CDATA[").append(_mapParams.get(paramName))
                        .append("]]>");
                sb.append("</" + paramName + ">");
            }
            sb.append("</parameters>");
        }
        sb.append("</post-data>");
        String result = sb.toString();
        sb.setLength(0);

        return result;
    }

    public static String makeMultiCallPostData(
            ServiceObject[] _arrServiceObjects) {
        // TODO
        return null;
    }
}