"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 CommUtils_1 = require("../utils/CommUtils");
const MsNodeType_1 = require("../enums/MsNodeType");
const MsLoadBalanceUtils_1 = require("../utils/MsLoadBalanceUtils");
const CallLink_1 = require("./CallLink");
/**
 * SideCar
 * @author wufenglin@rd.keytop.com.cn
 * @date 2010-08-04
 */
class SideCar {
    constructor() {
        this.updateCachePeriod = 1000 * 15;
        this.msLoadBalanceUtils = new MsLoadBalanceUtils_1.MsLoadBalanceUtils();
        this.fromNode = this.getFromNode();
        this.callLink = new CallLink_1.CallLink(this.fromNode);
        this.scheduleAtUpdateCache(this.updateCachePeriod);
    }
    /**
     * 构建网关地址
     * 1.如果是浏览器客户端，则网关地址需配置在前端
     * 2.如果是云端Node客户端，则网关地址需要从注册中心拉取
     * @param requestObj
     */
    buildHostUrl(requestObj) {
        var _a, _b, _c, _d, _e;
        return __awaiter(this, void 0, void 0, function* () {
            requestObj.fromNode = this.fromNode;
            requestObj.toNode = MsNodeType_1.MsNodeType.GATEWAY;
            //如果是浏览器客户端，则网关地址需配置在前端
            if (!CommUtils_1.CommUtils.isNodeClient()) {
                return "";
            }
            //如果是云端Node客户端，则网关地址需要从注册中心拉取
            const { uri, pid, version } = requestObj.request.headers;
            const loadBalance = yield this.msLoadBalanceUtils.getLoadBalance(pid, version, false);
            if (!loadBalance) {
                throw new Error(`There is no load balancing group for this service: ${pid}/${version}`);
            }
            const target = loadBalance.getTarget();
            if (!target) {
                throw new Error(`Background host does not exist for this service:${pid}/${version}`);
            }
            const callTarget = this.callLink.build(uri, target);
            requestObj.appCode = (_a = loadBalance.msRunning) === null || _a === void 0 ? void 0 : _a.appCode;
            requestObj.appName = (_b = loadBalance.msRunning) === null || _b === void 0 ? void 0 : _b.appName;
            requestObj.serviceCenterCode = (_c = loadBalance.msRunning) === null || _c === void 0 ? void 0 : _c.serviceCenterCode;
            requestObj.serviceCenterName = (_d = loadBalance.msRunning) === null || _d === void 0 ? void 0 : _d.serviceCenterName;
            requestObj.projectVersion = (_e = loadBalance.msRunning) === null || _e === void 0 ? void 0 : _e.projectVersion;
            requestObj.deploymentId = target.deployId;
            requestObj.podId = target.podId;
            requestObj.envCode = target.envCode;
            requestObj.toNode = callTarget.to;
            return callTarget.getUrl();
        });
    }
    /**
    * 定时更新缓存
    * @param period 执行周期 毫秒
    */
    scheduleAtUpdateCache(period) {
        setTimeout(() => __awaiter(this, void 0, void 0, function* () {
            yield this.msLoadBalanceUtils.updateCache();
            this.scheduleAtUpdateCache(period);
        }), period);
    }
    getFromNode() {
        if (CommUtils_1.CommUtils.isK8SClient()) {
            return MsNodeType_1.MsNodeType.K8S_CLIENT;
        }
        else {
            return MsNodeType_1.MsNodeType.CLIENT;
        }
    }
}
exports.default = new SideCar();
