"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__tsfTypeAliases = void 0;
exports.resolveMeshLinkAdvertiseUrl = resolveMeshLinkAdvertiseUrl;
exports.detectMeshIpAddress = detectMeshIpAddress;
const tslib_1 = require("tslib");
const _a = tslib_1.__importStar(require("@zyno-io/ts-server-foundation/type-metadata-runtime"));
const node_os_1 = require("node:os");
const app_1 = require("../../app");
function resolveMeshLinkAdvertiseUrl(options) {
    if (options.advertiseUrl)
        return normalizeWebSocketUrl(options.advertiseUrl, options.path);
    const configuredPodIp = process.env.POD_IP?.trim();
    const host = configuredPodIp || detectMeshIpAddress();
    const port = resolveListeningPort(options.httpServer);
    const bracketedHost = host.includes(':') ? `[${host}]` : host;
    return `ws://${bracketedHost}:${port}${normalizePath(options.path)}`;
}
function detectMeshIpAddress() {
    const candidates = Object.values((0, node_os_1.networkInterfaces)())
        .flatMap(entries => entries ?? [])
        .filter(entry => !entry.internal && (entry.family === 'IPv4' || entry.family === 'IPv6'));
    const ipv4 = candidates.find(entry => entry.family === 'IPv4');
    const selected = ipv4 ?? candidates[0];
    if (!selected)
        throw new Error('Unable to detect a non-loopback IP address for the sRPC mesh link');
    return selected.address;
}
function resolveListeningPort(httpServer) {
    const address = httpServer?.address() ?? getOptionalAppAddress();
    if (address && typeof address === 'object')
        return address.port;
    if (typeof address === 'string')
        throw new Error('sRPC mesh links require a TCP HTTP listener');
    try {
        return (0, app_1.getCurrentApp)().http.getPort();
    }
    catch {
        throw new Error('Unable to determine the sRPC mesh link port; provide meshLink.advertiseUrl');
    }
}
function getOptionalAppAddress() {
    try {
        return (0, app_1.getCurrentApp)().http.getAddress();
    }
    catch {
        return null;
    }
}
function normalizeWebSocketUrl(value, defaultPath) {
    const url = new URL(value);
    if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {
        throw new Error('sRPC mesh advertised URL must use ws: or wss:');
    }
    if (!url.pathname || url.pathname === '/')
        url.pathname = normalizePath(defaultPath);
    url.search = '';
    url.hash = '';
    return url.toString();
}
function normalizePath(path) {
    if (!path.startsWith('/'))
        return `/${path}`;
    return path;
}
exports.__tsfTypeAliases = _a.decodeCompactMetadataV1("[1,{\"MeshLinkAddressOptions\":{\"kind\":18,\"typeName\":\"MeshLinkAddressOptions\",\"types\":[{\"kind\":20,\"name\":\"advertiseUrl\",\"type\":{\"kind\":12,\"types\":[{\"kind\":6},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"path\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"httpServer\",\"type\":{\"kind\":12,\"types\":[{\"$tsfAlias\":[0,\"node:http\",\"Server\",\"Server\"]},{\"kind\":4}]},\"optional\":true}]}}]", [require]);
//# sourceMappingURL=address.js.map