package com.kingdee.eas.custom.integration.apimgt.log;

import com.kingdee.bos.Context;
import com.kingdee.eas.custom.integration.apimgt.ApiCallLogFactory;
import com.kingdee.eas.custom.integration.apimgt.ApiCallLogInfo;
import com.kingdee.eas.custom.integration.apimgt.IApiCallLog;
import com.kingdee.eas.custom.integration.base.util.SHRApiUtils;
import com.kingdee.util.DateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * 接口调用日志服务。
 * 在拦截器 afterCompletion 中调用，记录每次 OpenAPI 调用的入参、响应和耗时。
 */
public class ApiCallLogService {

    private static final Logger logger = LoggerFactory.getLogger(ApiCallLogService.class);

    /**
     * 响应体最大长度，超过则截断
     */
    private static final int MAX_RESPONSE_BODY_LENGTH = 2000;

    /**
     * 记录一次接口调用日志。
     *
     * @param platform       调用方平台编码（匿名/无调用方可传 null）
     * @param apiPath        接口路径
     * @param httpMethod     请求方式
     * @param requestUrl     完整请求 URL
     * @param requestParams  请求入参（JSON 字符串或 queryString）
     * @param requestIp      调用方 IP
     * @param responseBody   响应体（过长自动截断）
     * @param httpStatusCode HTTP 状态码
     * @param success        业务是否成功
     * @param errorMsg       异常信息（无异常传 null）
     * @param costTime       接口耗时（毫秒）
     */
    public void record(String platform, String apiPath, String httpMethod,
                       String requestUrl, String requestParams, String requestIp,
                       String responseBody, int httpStatusCode,
                       boolean success, String errorMsg, long costTime) {
        try {
            Context ctx = SHRApiUtils.getContext();
            IApiCallLog iApiCallLog = ApiCallLogFactory.getLocalInstance(ctx);

            ApiCallLogInfo info = new ApiCallLogInfo();
            info.setPlatform(platform);
            info.setApiPath(apiPath);
            info.setHttpMethod(httpMethod);
            info.setRequestUrl(requestUrl);
            info.setRequestParams(requestParams);
            info.setRequestIp(requestIp);
            info.setResponseBody(truncate(responseBody, MAX_RESPONSE_BODY_LENGTH));
            info.setHttpStatusCode(httpStatusCode);
            info.setSuccess(success);
            info.setErrorMsg(errorMsg);
            info.setCostTime((int) costTime);

            info.setBizDate(DateTimeUtils.truncateDate(new Date()));
            iApiCallLog.save(info);
        } catch (Exception e) {
            logger.error("保存接口调用日志失败: {} {}", httpMethod, apiPath, e);
        }
    }

    private String truncate(String value, int maxLen) {
        if (value == null) {
            return null;
        }
        if (value.length() <= maxLen) {
            return value;
        }
        return value.substring(0, maxLen) + "...[truncated]";
    }
}
