"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const MsConfig_1 = require("./mslib/MsConfig");
const SideCar_1 = require("./sidecar/SideCar");
const RequestObj_1 = require("./sidecar/RequestObj");
const CommUtils_1 = require("./utils/CommUtils");
const MsConsts_1 = require("./defines/MsConsts");
const Logger_1 = require("./mslib/Logger");
/**
 * 微服务客户端使用接口
 * 微服务主地址、appId、appKey -> 配置文件中设置
 * traceId -> 客户端内部处理，从当前request的header获取，不可为空，如果当前request无值，那么客户端生成一个uuid填入本次调用的header
 * @author WuFenglin
 **/
class ServiceClient {
    beforeMsCall(headers) {
        let parentCallId = "";
        let traceId = CommUtils_1.CommUtils.uuid();
        let callId = CommUtils_1.CommUtils.uuid();
        let callLink = `[${CommUtils_1.CommUtils.getLocalIP()}]`;
        headers[MsConsts_1.MsConsts.PARENT_CALL_ID_KEY] = parentCallId;
        headers[MsConsts_1.MsConsts.TRACE_ID_KEY] = traceId;
        headers[MsConsts_1.MsConsts.CALL_ID_KEY] = callId;
        headers[MsConsts_1.MsConsts.SPAN_ID_KEY] = callId;
        headers[MsConsts_1.MsConsts.CALL_LINK_KEY] = callLink;
    }
    /**
     * 微服务REST请求
     * @param method 请求方法 GET|POST|PUT...
     * @param contentType 上下文类型
     * @param headers   //请求头信息
     * @param parameters //请求参数
     */
    request(method, contentType, headers, parameters) {
        return __awaiter(this, void 0, void 0, function* () {
            const beginTime = this.currentTimeMillis();
            let requestObj;
            let response;
            try {
                requestObj = new RequestObj_1.RequestObj(MsConfig_1.default, method, headers, parameters);
                const url = yield SideCar_1.default.buildHostUrl(requestObj);
                this.beforeMsCall(headers);
                response = yield MsConfig_1.default.httpClient.request(url, method, contentType, headers, parameters);
                return response;
            }
            finally {
                this.addCallLog(requestObj, response, beginTime);
            }
        });
    }
    addCallLog(requestObj, response, beginTime) {
        if (requestObj == null) {
            return;
        }
        const msHttpCallLog = {};
        const { callId, traceId, parentCallId, sid } = requestObj.request.headers;
        msHttpCallLog.callId = callId;
        msHttpCallLog.callTime = beginTime;
        if (requestObj.fromNode != null) {
            msHttpCallLog.fromNode = requestObj.fromNode;
        }
        if (requestObj.toNode != null) {
            msHttpCallLog.toNode = requestObj.toNode;
        }
        msHttpCallLog.method = requestObj.method;
        msHttpCallLog.traceId = traceId;
        msHttpCallLog.parentCallId = parentCallId;
        msHttpCallLog.data = requestObj;
        msHttpCallLog.callUrl = requestObj.callUrl;
        msHttpCallLog.sid = sid;
        msHttpCallLog.pid = CommUtils_1.CommUtils.leftStrEx(sid, ".");
        msHttpCallLog.url = CommUtils_1.CommUtils.rightStr(sid, ".");
        msHttpCallLog.consumeTime = (this.currentTimeMillis() - beginTime);
        if (response != null) {
            msHttpCallLog.response = response;
        }
        Logger_1.logger.info("%j", msHttpCallLog);
    }
    currentTimeMillis() {
        return new Date().getTime();
    }
}
exports.ServiceClient = ServiceClient;
