"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 HttpMethodType_1 = require("./enums/HttpMethodType");
const RequestBodyType_1 = require("./enums/RequestBodyType");
const SimpleHttpUtil_1 = require("./utils/http/SimpleHttpUtil");
const GatewayConfig_1 = require("./config/GatewayConfig");
const StcHttpRequestObj_1 = require("./model/StcHttpRequestObj");
const SideCar_1 = require("./sidecar/SideCar");
const UuidUtil_1 = require("./utils/UuidUtil");
const IPUtil_1 = require("./utils/IPUtil");
const MsConsts_1 = require("./defines/MsConsts");
/**
 * 微服务客户端使用接口
 * 微服务主地址、appId、appKey -> 配置文件中设置
 * traceId -> 客户端内部处理，从当前request的header获取，不可为空，如果当前request无值，那么客户端生成一个uuid填入本次调用的header
 * @author WuFenglin
 **/
class ServiceClientImpl {
    constructor(serviceClientConfig) {
        this.gatewayConfig = GatewayConfig_1.GatewayConfig.make();
        this.serviceClientConfig = serviceClientConfig;
        this.simpleHttpUtil = new SimpleHttpUtil_1.SimpleHttpUtil(this.serviceClientConfig);
    }
    beforeMsCall(sid, version, requestObj) {
        let parentCallId = "";
        let traceId = UuidUtil_1.default.get();
        let callId = UuidUtil_1.default.get();
        let callLink = `[${IPUtil_1.default.getLocalIP()}]`;
        const header = requestObj.header;
        if (header) {
            header[MsConsts_1.MsConsts.PARENT_CALL_ID_KEY] = parentCallId;
            header[MsConsts_1.MsConsts.TRACE_ID_KEY] = traceId;
            header[MsConsts_1.MsConsts.CALL_ID_KEY] = callId;
            header[MsConsts_1.MsConsts.SPAN_ID_KEY] = callId;
            header[MsConsts_1.MsConsts.CALL_LINK_KEY] = callLink;
        }
        if (this.serviceClientConfig.httpClientHook != null) {
            this.serviceClientConfig.httpClientHook.beforeMsCall(sid, version, requestObj);
        }
    }
    afterMsCall(sid, version, requestObj, result) {
        var _a;
        (_a = this.serviceClientConfig.httpClientHook) === null || _a === void 0 ? void 0 : _a.afterMsCall(sid, version, requestObj, result);
    }
    addCallLog(beginTime, requestObj, result) {
    }
    call(httpMethod, sid, version, tags, header, params, bodyObj, authType, bodyType) {
        return __awaiter(this, void 0, void 0, function* () {
            let requestBodyObj = bodyObj;
            if (bodyType == RequestBodyType_1.RequestBodyType.WWW_FORM) {
                requestBodyObj = params;
            }
            return this.sendRequest(httpMethod, sid, version, tags, header, params, requestBodyObj, authType, bodyType);
        });
    }
    get(sid, version, tags, header, params, authType) {
        return __awaiter(this, void 0, void 0, function* () {
            return this.sendRequest(HttpMethodType_1.HttpMethodType.GET, sid, version, tags, header, params, {}, authType, RequestBodyType_1.RequestBodyType.WWW_FORM);
        });
    }
    postFiles(sid, version, tags, header, params, files, authType) {
        let bodyObj = params || {};
        return this.sendRequest(HttpMethodType_1.HttpMethodType.UPLOAD_FILE, sid, version, tags, header, params, bodyObj, authType, RequestBodyType_1.RequestBodyType.WWW_FORM, files);
    }
    sendRequest(method, sid, version, tags, header, params, bodyObj, authType, bodyType, files) {
        return __awaiter(this, void 0, void 0, function* () {
            const beginTime = this.currentTimeMillis();
            let result;
            let requestObj;
            try {
                this.gatewayConfig.check();
                const signMethod = method == HttpMethodType_1.HttpMethodType.UPLOAD_FILE ? HttpMethodType_1.HttpMethodType.POST : method;
                requestObj = new StcHttpRequestObj_1.StcHttpRequestObj(this.gatewayConfig, signMethod, sid, version, tags, params, header, bodyObj, authType, bodyType);
                const url = SideCar_1.default.buildHostUrl(this.gatewayConfig, sid, version, requestObj);
                requestObj.callUrl = url;
                this.beforeMsCall(sid, version, requestObj);
                switch (method) {
                    case HttpMethodType_1.HttpMethodType.GET:
                        result = yield this.simpleHttpUtil.get(url, requestObj.params, requestObj.header);
                        break;
                    case HttpMethodType_1.HttpMethodType.UPLOAD_FILE:
                        if (files != null) {
                            result = yield this.simpleHttpUtil.uploadFiles(url, requestObj.params, files, requestObj.header);
                        }
                        else {
                            throw new Error('Upload Error files is not empty...');
                        }
                        break;
                    default:
                        result = yield this.simpleHttpUtil.call(method, url, requestObj.params, bodyObj, requestObj.header, bodyType);
                        break;
                }
                return result.data;
            }
            finally {
                this.addCallLog(beginTime, requestObj, result);
                this.afterMsCall(sid, version, requestObj, result);
            }
        });
    }
    currentTimeMillis() {
        return new Date().getTime();
    }
}
exports.ServiceClientImpl = ServiceClientImpl;
//# sourceMappingURL=ServiceClientImpl.js.map