/**
 * @target 서버통신 관련 공통함수
 */

/**
 * 서버통신 관련 공통함수를 제공하는 개체입니다.
 *
 * @type {object}
 * @class configLib
 * @namespace configLib
 */
var ajaxLib = {};

/**
 * 지정한 옵션으로 서버와 AJAX 통신을 수행합니다.
 *
 * @author SONG WONSEOK
 * @date 2019.09.01.
 * @memberOf ajaxLib
 * @param {string} action - 서버의 API 액션 경로를 지정합니다
 * @param {object} options - 옵션 기타 사항들을 지정합니다.
 * @param {object} [options.mode] - 동기/비동기 모드를 지정합니다.<br>
 *            (asynchronous(기본값), synchronous)
 * @param {object} [options.mediatype] - 콘텐츠 유형을 지정합니다.<br>
 *            (application/xml, application/x-www-form-urlencoded, application/json(기본값), text/xml)
 * @param {object} [options.method] - HTTP 동사를 지정합니다.<br>
 *            (POST(기본값), GET, PUT, DELETE)
 * @param {object} [options.requestData] - 서버로 전달할 Request 데이터입니다.<br>
 *            mediatype과 일치하는 데이터 형식을 전달해야 합니다.
 * @param {object} [options.processMsg] - 메시지를 지정합니다.
 * @param {object} [options.requestHeader] - Request Header 정보를 담고 있는 JSON 개체
 * @param {object} [options.callback] - 콜백 함수명입니다.
 * @param {object} [options.errCallback] - 오류 콜백 함수명입니다.
 * @returns {object} 서버에서 반환한 데이터
 */
/**
 * 한글완성형 체크
 */
ajaxLib.dataValidation = function(data1){
    // 한글완성형 체크
    var jsonData = strLib.isJSON(data1) ? strLib.serialize(data1) : data1;
    var noKscList = strLib.isKSC5601(jsonData);
    if(noKscList.length > 0) {
        alert("잘못된 한글이 있습니다.\n[ "+noKscList[0]+" ]");
        return false;
    }
    return true;
}
ajaxLib.ajax = function(action, options) {

    try {
        if (!action) {
            // 개발자 메시지: 영문지원 안 함
            throw "서버와 통신하기 위해서 필요한 액션 경로를 지정해주십시오.";
        } else if (!options) {
            // 개발자 메시지: 영문지원 안 함
            throw "서버와 통신하기 위해서 필요한 기타 사항들을 지정해주십시오.";
        }
        // 한글완성형 체크
        if(!ajaxLib.dataValidation(options.requestData)){
            return false;
        }

        // 동기/비동기 모드를 지정합니다.
        var mode = options.mode || "asynchronous";

        // 콘텐츠 유형을 지정합니다.
        var mediatype = options.mediatype || "application/json";

        // HTTP 동사를 지정합니다.
        var method = options.method || "POST";

        // 메시지를 지정합니다.
        var processMsg = "";
        if(options.processMsg == "yes"){
            processMsg = "처리 중 입니다.";
        }
        if(!(typeof options.processMsg == "undefined") && options.processMsg.length > 3){
            processMsg = options.processMsg;
        }


        // 서버로 전달할 Request 데이터입니다.
        //var requestData = strLib.serialize(options.requestData)
        var requestData = options.requestData ? strLib.serialize(options.requestData) : "";

        // 콜백/오류 콜백 함수명입니다.
        var callback = options.callback || "";
        var errCallback = options.errCallback || "";

        var result = null;

        $w.ajax({
            action : "/" + action,
            mode : mode,
            mediatype : mediatype,
            method : method.toUpperCase(),
            processMsg : processMsg,
            requestData : requestData,
            requestHeader : options.requestHeader || "",
            beforeAjax : function(e) {
                // 요청 전에 실행되는 함수입니다. 여기서 false를 반환하면 작업이 중단됩나다.
            },
            success : function(e) {
                result = ajaxLib._callBackAjax(e, {
                    result : "SUCCESS",
                    argument : requestData,
                    callback : callback,
                    mediatype : mediatype.toLowerCase(),
                    mode : mode.toLowerCase()
                });
            },
            error : function(e) {

                ajaxLib._callBackAjax(e, {
                    result : "ERROR",
                    argument : requestData,
                    errCallback : errCallback,
                    mediatype : mediatype.toLowerCase(),
                    mode : mode.toLowerCase()
                });
            }
        });

        return result;
    } catch (e) {
        //$W.exception.printStackTrace(e);
        //commLib.log("ajaxLib.ajax: " + e);
    }
};

/**
 * [내부용] 서버와 AJAX 통신을 수행한 결과를 처리하고 사용자가 지정한 콜백을 수행합니다.
 *
 * @author SONG WONSEOK
 * @date 2019.09.01
 * @memberOf ajaxLib
 * @param {object} e - XHR 이 매개변수로 반환한 개체입니다.
 * @param {object} statusObj - 요청에 전달된 정보와 상태 정보를 담고 있습니다.
 * @returns {object} 서버에서 반환한 데이터
 */
ajaxLib._callBackAjax = function(e, statusObj) {
    try {
        // 서버에서 반환된 결과를 정리합니다.
        // var argumentJson = strLib.parse(statusObj.argument);
        var responseBody = null;
        if (statusObj.mediatype == "application/json") {
            var responseText = e.responseText;
            if (strLib.isEmpty(responseText, true)) {
                responseBody = {};
            }
            /*
              List<?> 형태를 리턴하게되면 [] 로 시작하므로 (responseText && responseText.trim().indexOf("[")) == 0
              or 조건을 추가함. yongsang 2017.08.04
            */
            else if ((responseText && responseText.trim().indexOf("{")) == 0
                    || (responseText && responseText.trim().indexOf("[")) == 0) {
                responseBody = strLib.parse(responseText.trim());
            } else {
                return null;
            }
        } else if (statusObj.mediatype == "application/xml") {
            responseBody = WebSquare.xml.parse("<ret />");
            if (typeof e.responseBody != "undefined") {
                responseBody = WebSquare.xml.parse(e.responseBody);
            }
        } else {
            responseBody = e.responseText;
        }

        if (statusObj.result == "SUCCESS") {
            // AJAX 통신 성공 후처리를 수행합니다.
            // 일반 오류메시지 처리
            var needErrorCallback = false;
            if (responseBody.msgCode && responseBody.msgCode == "error") {
                needErrorCallback = true;

                if (responseBody.msgErrorCode) {
                    var msgErrorCode = responseBody.msgErrorCode;
                    if (msgErrorCode == "validationError") {
                        // valid.0001: 서버 측 유효성 검사에 실패했습니다.
                        alert(commLib.getMessage("valid.0001"));
                    } else if (msgErrorCode == "duplicateKeyError") {
                        // valid.0002: 중복된 데이터가 이미 존재합니다.
                        alert(commLib.getMessage("valid.0002"));
                    } else if (msgErrorCode == "serverError") {
                        // sysm.0001: 서버에서 알 수 없는 오류가 발생했습니다.
                        alert(commLib.getMessage("sysm.0001"));
                    } else if (msgErrorCode == "loginError") {
                        // 로그인 오류는 화면에서 별도 처리
                        needErrorCallback = false;
                    } else if (msgErrorCode == "SessionInvalidError") {
                        commLib.moveToLoginPage();
                    }
                } else {
                    // sysm.0001: 서버에서 알 수 없는 오류가 발생했습니다.
                    alert(commLib.getMessage("sysm.0001"));
                }
            }

            if (needErrorCallback) {
                // 사용자 지정 오류 콜백을 수행합니다.
                if (statusObj.errCallback != "") {
                    var errCallback = window[statusObj.errCallback];
                    if (!errCallback) {
                        errCallback = window.scwin[statusObj.errCallback];
                    }
                    if (errCallback && typeof errCallback == "function") {
                        errCallback(responseBody, e);
                    }
                }
            } else {
                // 사용자 지정 콜백을 수행합니다.
                if (statusObj.callback != "") {
                    var callback = window[statusObj.callback];
                    /*
                     * callback에 문자열이 아닌 function을 줄 경우 단순히 !callback 조건만 비교해서는
                     * function이 실행되지 않는 문제가 있어 수정함. yongsang 2017.08.04
                     */
                    if (!callback && typeof statusObj.callback != "function") {
                        callback = window.scwin[statusObj.callback];
                    } else {
                        statusObj.callback(responseBody, e);
                    }
                }
            }

            if (statusObj.mode == "synchronous") {
                return responseBody;
            }
        } else if (statusObj.result == "ERROR") {
            // AJAX 통신 실패 후처리를 수행합니다.

            // sysm.0001: 서버에서 알 수 없는 오류가 발생했습니다.
            // alert(commLib.getMessage("sysm.0001"));

            /*
             * 에러 callback이 있는 경우에는 에러에 대해 직접 handling 하도록 하고
             * 에러 callback이 없는 경우에는 에러를 공통으로 처리하도록 코드를 수정. yongsang 2017.08.07
             */
        	responseBody = strLib.parse(e.responseBody.startsWith("text/") ? e.responseBody.substring(5) : e.responseBody);
            // 사용자 지정 오류 콜백을 수행합니다.
            if (statusObj.errCallback != "") {
                var errCallback = window[statusObj.errCallback];
                if (!errCallback && typeof errCallback == "function") {
                    errCallback = window.scwin[statusObj.errCallback];
                } else {
                    statusObj.errCallback(responseBody, e);
                }
            } else {
                if (responseBody.hasOwnProperty('messageCode')) {
                    if(responseBody.errorCode == -20000){
                        if(responseBody.busiMessage != null) {
                            alert(responseBody.busiMessage);
                        }else{
                            alert(responseBody.message);
                        }
                    }else{
                        if(responseBody.messageCode != null){
                            alert(commLib.getMessage(responseBody.messageCode));
                        }else{
                            alert(responseBody.message);
                        }
                    }
                    // 세션 타임아웃 또는 로그인하지 않고 접근한 경우.
                    if (responseBody.errorCode == -700) {
                        commLib.moveToW2xPath("/ux/main/login.xml");
                    }
                }
            }

            if (statusObj.mode == "synchronous") {
                return responseBody;
            }
        }
    } catch (e) {
        //$W.exception.printStackTrace(e);
        //commLib.log("ajaxLib._callBackAjax: " + e);
    }
};