/**
 * Bridge 实例自动注册服务
 *
 * 实现 Bridge 实例启动后自动向调度中心注册的功能
 *
 * 配置来源（优先级从高到低）：
 * 1. 环境变量
 * 2. 用户目录下的 .aws-bridge/config.json 文件
 */
import axios from "axios";
import os from "node:os";
import path from "node:path";
import fs from "node:fs";
import { logger } from "../utils/logger.js";
import { schedulerBaseUrl } from "../config.js";
import { clearRuntimeBinding, clearScopedRuntimeAccessToken, getRuntimeAccessToken, getRuntimeBindingPublicState, loadRuntimeBinding, normalizeSchedulerBaseUrl, saveRuntimeBinding, saveScopedRuntimeAccessToken, } from "./runtime-binding.js";
// 默认配置
const DEFAULT_CONFIG = {
    enabled: false,
    serverUrl: schedulerBaseUrl,
    preferSameLanIp: true,
    maxRetries: 5,
    retryInterval: 5000,
};
let registrationState = {
    registered: false,
    registrations: {},
};
let cachedConfiguredConnectionKeys = [];
export function getConfiguredConnectionKeys() {
    return [...cachedConfiguredConnectionKeys];
}
function normalizeOptionalString(value) {
    if (value == null) {
        return undefined;
    }
    const normalized = String(value).trim();
    return normalized || undefined;
}
function normalizeSchedulerHttpBaseUrl(value) {
    return normalizeSchedulerBaseUrl(value);
}
function normalizeOptionalBoolean(value) {
    if (typeof value === "boolean") {
        return value;
    }
    if (typeof value === "string") {
        const normalized = value.trim().toLowerCase();
        if (["true", "1", "yes", "y"].includes(normalized)) {
            return true;
        }
        if (["false", "0", "no", "n"].includes(normalized)) {
            return false;
        }
    }
    return undefined;
}
function normalizeOptionalNumber(value) {
    if (value == null || value === "") {
        return undefined;
    }
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : undefined;
}
function normalizeTargetConfig(source) {
    const serverUrl = normalizeOptionalString(source.serverUrl) ||
        normalizeOptionalString(source.schedulerBaseUrl);
    const connectionKey = normalizeOptionalString(source.connectionKey) ||
        normalizeOptionalString(source.password);
    return {
        enabled: normalizeOptionalBoolean(source.enabled),
        serverUrl,
        tenantId: normalizeOptionalString(source.tenantId),
        userKey: normalizeOptionalString(source.userKey),
        connectionKey,
        instanceName: normalizeOptionalString(source.instanceName),
        projectName: normalizeOptionalString(source.projectName),
        roleName: normalizeOptionalString(source.roleName),
        workspacePath: normalizeOptionalString(source.workspacePath),
        registerIp: normalizeOptionalString(source.registerIp),
        virtualIp: normalizeOptionalString(source.virtualIp),
        preferSameLanIp: normalizeOptionalBoolean(source.preferSameLanIp),
        maxRetries: normalizeOptionalNumber(source.maxRetries),
        retryInterval: normalizeOptionalNumber(source.retryInterval),
    };
}
/**
 * 配置文件路径
 */
export function getAutoRegisterConfigFilePath() {
    const homeDir = os.homedir();
    return path.join(homeDir, ".aws-bridge", "config.json");
}
/**
 * 从配置文件加载配置
 *
 * 配置文件位置：~/.aws-bridge/config.json
 *
 * 配置文件格式：
 * {
 *   "connectionKey": "bridge-password", // 可选，server/面板连接该 bridge 的密钥
 *   "autoRegisterTargets": [
 *     {
 *       "serverUrl": "http://scheduler-host:7380", // 必填，要主动注册的 server 地址
 *       "userKey": "aws_live_xxx",                 // 必填，用户 API Key
 *       "instanceName": "my-bridge",               // 必填/可选，默认主机名
 *       "registerIp": "192.168.1.25",              // 可选，优先作为注册 IP
 *       "connectionKey": "bridge-password"          // 可选，不填则使用顶层 connectionKey
 *     }
 *   ],
 *
 *   // 兼容旧版单目标配置：
 *   "userKey": "aws_live_xxx",     // 必填，用户 API Key
 *   "tenantId": "xxx",             // 可选，租户 ID（不填则自动推导）
 *   "instanceName": "my-bridge",   // 可选，默认使用主机名
 *   "projectName": "default",     // 可选
 *   "roleName": "Bridge",          // 可选
 *   "workspacePath": "/path/to/workspace",  // 可选
 *   "registerIp": "192.168.1.25", // 可选，优先作为注册 IP
 *   "virtualIp": "10.144.144.1", // 可选，兼容 EasyTier 虚拟 IP
 *   "maxRetries": 5,              // 可选
 *   "retryInterval": 5000          // 可选
 * }
 */
function loadConfigFromFile() {
    const configPath = getAutoRegisterConfigFilePath();
    try {
        if (!fs.existsSync(configPath)) {
            logger.debug(`[AutoRegister] 配置文件不存在: ${configPath}`);
            return null;
        }
        const content = fs.readFileSync(configPath, "utf-8");
        const config = JSON.parse(content);
        logger.info(`[AutoRegister] 从配置文件加载配置: ${configPath}`);
        return normalizeTargetConfig(config);
    }
    catch (error) {
        const err = error;
        logger.warn(`[AutoRegister] 读取配置文件失败: ${configPath}, error: ${err.message}`);
        return null;
    }
}
function loadTargetsFromFile() {
    const configPath = getAutoRegisterConfigFilePath();
    try {
        if (!fs.existsSync(configPath)) {
            return [];
        }
        const content = fs.readFileSync(configPath, "utf-8");
        const config = JSON.parse(content);
        const topLevel = normalizeTargetConfig(config);
        const rawTargets = Array.isArray(config.autoRegisterTargets)
            ? config.autoRegisterTargets
            : [];
        if (rawTargets.length === 0) {
            return topLevel.userKey ? [topLevel] : [];
        }
        return rawTargets
            .filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item)))
            .map((item) => {
            const target = normalizeTargetConfig(item);
            return {
                ...topLevel,
                ...target,
                connectionKey: target.connectionKey || topLevel.connectionKey,
            };
        });
    }
    catch (error) {
        const err = error;
        logger.warn(`[AutoRegister] 读取自动注册目标失败: ${configPath}, error: ${err.message}`);
        return [];
    }
}
/**
 * 从环境变量加载配置
 */
function loadConfigFromEnv() {
    const envConfig = {};
    if (process.env.AWS_AUTO_REGISTER === "true") {
        envConfig.enabled = true;
    }
    if (process.env.AWS_RUNTIME_SCHEDULER_BASE_URL) {
        envConfig.serverUrl = process.env.AWS_RUNTIME_SCHEDULER_BASE_URL;
    }
    if (process.env.AWS_TENANT_ID) {
        envConfig.tenantId = process.env.AWS_TENANT_ID;
    }
    if (process.env.AWS_USER_KEY) {
        envConfig.userKey = process.env.AWS_USER_KEY;
    }
    if (process.env.AWS_BRIDGE_CONNECTION_KEY) {
        envConfig.connectionKey = process.env.AWS_BRIDGE_CONNECTION_KEY;
    }
    if (process.env.AWS_INSTANCE_NAME) {
        envConfig.instanceName = process.env.AWS_INSTANCE_NAME;
    }
    if (process.env.AWS_PROJECT_NAME) {
        envConfig.projectName = process.env.AWS_PROJECT_NAME;
    }
    if (process.env.AWS_ROLE_NAME) {
        envConfig.roleName = process.env.AWS_ROLE_NAME;
    }
    if (process.env.AWS_WORKSPACE_PATH) {
        envConfig.workspacePath = process.env.AWS_WORKSPACE_PATH;
    }
    if (process.env.AWS_REGISTER_IP) {
        envConfig.registerIp = process.env.AWS_REGISTER_IP;
    }
    if (process.env.AWS_VIRTUAL_IP) {
        envConfig.virtualIp = process.env.AWS_VIRTUAL_IP;
    }
    if (process.env.AWS_PREFER_SAME_LAN_IP) {
        envConfig.preferSameLanIp =
            normalizeOptionalBoolean(process.env.AWS_PREFER_SAME_LAN_IP) ?? true;
    }
    if (process.env.AWS_REGISTER_MAX_RETRIES) {
        envConfig.maxRetries = parseInt(process.env.AWS_REGISTER_MAX_RETRIES, 10);
    }
    if (process.env.AWS_REGISTER_RETRY_INTERVAL) {
        envConfig.retryInterval = parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL, 10);
    }
    return envConfig;
}
/**
 * 加载自动注册配置
 *
 * 优先级：环境变量 > 配置文件 > 默认值
 *
 * 如果没有配置文件且没有环境变量，则不启用自动注册
 */
export function loadConfig() {
    // 1. 尝试从配置文件加载
    const fileConfig = loadConfigFromFile();
    // 2. 从环境变量加载（可覆盖配置文件）
    const envConfig = loadConfigFromEnv();
    // 3. 合并配置：环境变量优先级最高
    const merged = {
        ...DEFAULT_CONFIG,
        ...(fileConfig || {}),
        ...envConfig,
    };
    // 4. 设置默认实例名（如果未配置）
    const instanceName = merged.instanceName || os.hostname();
    // 5. 判断是否启用
    // 如果环境变量明确设置了 AWS_AUTO_REGISTER，使用环境变量的值
    // 否则，如果配置文件存在（无论是否有内容），则启用自动注册
    let enabled = false;
    if (process.env.AWS_AUTO_REGISTER !== undefined) {
        enabled = process.env.AWS_AUTO_REGISTER === "true";
    }
    else if (fileConfig) {
        enabled = true;
    }
    return {
        enabled,
        serverUrl: merged.serverUrl || schedulerBaseUrl,
        tenantId: merged.tenantId || "", // 保持为空字符串，后续会通过userKey自动推导
        userKey: merged.userKey || "",
        connectionKey: merged.connectionKey,
        instanceName,
        projectName: merged.projectName,
        roleName: merged.roleName,
        workspacePath: merged.workspacePath,
        registerIp: merged.registerIp,
        virtualIp: merged.virtualIp,
        preferSameLanIp: merged.preferSameLanIp !== false,
        maxRetries: merged.maxRetries,
        retryInterval: merged.retryInterval,
    };
}
export function loadConfigs() {
    const fileTargets = loadTargetsFromFile();
    const envConfig = loadConfigFromEnv();
    const targets = fileTargets.length > 0 ? fileTargets : [loadConfigFromFile() || {}];
    const configs = targets.map((target) => {
        const merged = {
            ...DEFAULT_CONFIG,
            ...target,
            ...envConfig,
        };
        let enabled = false;
        if (process.env.AWS_AUTO_REGISTER !== undefined) {
            enabled = process.env.AWS_AUTO_REGISTER === "true";
        }
        else {
            enabled = fileTargets.length > 0 || Boolean(merged.userKey);
        }
        return {
            enabled,
            serverUrl: merged.serverUrl || schedulerBaseUrl,
            tenantId: merged.tenantId || "",
            userKey: merged.userKey || "",
            connectionKey: merged.connectionKey,
            instanceName: merged.instanceName || os.hostname(),
            projectName: merged.projectName,
            roleName: merged.roleName,
            workspacePath: merged.workspacePath,
            registerIp: merged.registerIp,
            virtualIp: merged.virtualIp,
            preferSameLanIp: merged.preferSameLanIp !== false,
            maxRetries: merged.maxRetries,
            retryInterval: merged.retryInterval,
        };
    });
    cachedConfiguredConnectionKeys = configs
        .map((config) => config.connectionKey)
        .filter((key) => Boolean(key && key.trim()));
    return configs;
}
/**
 * 获取本机所有非内部 IPv4 地址
 */
function getAllLocalIpAddresses() {
    const interfaces = os.networkInterfaces();
    const addresses = [];
    for (const name of Object.keys(interfaces)) {
        const nets = interfaces[name];
        if (!nets)
            continue;
        for (const net of nets) {
            // 跳过内部和非 IPv4 地址
            if (net.family === "IPv4" && !net.internal) {
                addresses.push({
                    address: net.address,
                    netmask: net.netmask,
                    name: name,
                });
            }
        }
    }
    return addresses;
}
/**
 * 将 IP 地址转换为整数
 */
function ipToInt(ip) {
    const parts = ip.split(".").map(Number);
    return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
}
/**
 * 判断两个 IP 是否在同一子网
 */
function isSameSubnet(ip1, ip2, netmask) {
    const ip1Int = ipToInt(ip1);
    const ip2Int = ipToInt(ip2);
    const maskInt = ipToInt(netmask);
    return (ip1Int & maskInt) === (ip2Int & maskInt);
}
/**
 * 从 URL 中提取 IP 地址
 */
function extractIpFromUrl(url) {
    try {
        const urlObj = new URL(url);
        // 如果是主机名，尝试解析
        if (urlObj.hostname === "localhost" || urlObj.hostname === "127.0.0.1") {
            return "127.0.0.1";
        }
        // 检查是否是有效的 IP 地址
        const ipPattern = /^(\d{1,3}\.){3}\d{1,3}$/;
        if (ipPattern.test(urlObj.hostname)) {
            return urlObj.hostname;
        }
        // 对于主机名，返回 null（无法直接判断子网）
        return null;
    }
    catch {
        return null;
    }
}
/**
 * 获取与调度中心同局域网的本机 IP 地址
 *
 * 策略：
 * 1. 解析调度中心 URL 获取其 IP
 * 2. 遍历本机网卡，找到与调度中心同子网的 IP
 * 3. 如果找不到同子网 IP，返回 127.0.0.1
 */
function getPreferredIpAddress(schedulerUrl) {
    const allIps = getAllLocalIpAddresses();
    if (allIps.length === 0) {
        logger.warn("[AutoRegister] 未找到任何非内部 IP 地址，使用 127.0.0.1");
        return "127.0.0.1";
    }
    // 尝试从调度中心 URL 提取 IP
    const schedulerIp = extractIpFromUrl(schedulerUrl);
    if (schedulerIp) {
        // 查找与调度中心同子网的 IP
        for (const ipInfo of allIps) {
            if (isSameSubnet(ipInfo.address, schedulerIp, ipInfo.netmask)) {
                logger.info(`[AutoRegister] 找到与调度中心同子网的 IP: ${ipInfo.address} (网卡: ${ipInfo.name}, 子网掩码: ${ipInfo.netmask})`);
                return ipInfo.address;
            }
        }
        logger.warn(`[AutoRegister] 未找到与调度中心 (${schedulerIp}) 同子网的本机 IP，使用 127.0.0.1`);
    }
    else {
        logger.warn("[AutoRegister] 无法解析调度中心 IP，使用 127.0.0.1");
    }
    return "127.0.0.1";
}
/**
 * 获取本机 IP 地址（兼容旧接口）
 */
function getLocalIpAddress(targetServerUrl = schedulerBaseUrl) {
    return getPreferredIpAddress(targetServerUrl);
}
function resolveRuntimeBridgeBaseUrl(config) {
    const port = process.env.AWS_RUNTIME_BRIDGE_PORT || 18081;
    const localIp = config.preferSameLanIp === false
        ? "127.0.0.1"
        : getLocalIpAddress(config.serverUrl || schedulerBaseUrl);
    return `http://${config.registerIp || config.virtualIp || localIp}:${port}`;
}
function loadPrimaryLifecycleConfig() {
    return loadConfigs()[0] || loadConfig();
}
function resolveRegisteredSchedulerBaseUrl(instanceId) {
    if (!instanceId) {
        return undefined;
    }
    const registration = Object.entries(registrationState.registrations).find(([, registeredInstanceId]) => registeredInstanceId === instanceId);
    return registration?.[0];
}
function resolveLifecycleSchedulerBaseUrl(config, instanceId) {
    const registeredServerUrl = resolveRegisteredSchedulerBaseUrl(instanceId);
    if (registeredServerUrl) {
        return registeredServerUrl;
    }
    const configuredServerUrl = normalizeOptionalString(config.serverUrl);
    if (configuredServerUrl &&
        (configuredServerUrl !== schedulerBaseUrl ||
            Boolean(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))) {
        return configuredServerUrl;
    }
    const binding = loadRuntimeBinding();
    const pairedSchedulerBaseUrl = normalizeOptionalString(binding.schedulerBaseUrl);
    if (binding.status === "paired" && pairedSchedulerBaseUrl) {
        return pairedSchedulerBaseUrl;
    }
    return configuredServerUrl || schedulerBaseUrl;
}
/**
 * 执行注册请求
 */
async function doRegister(config) {
    const instanceName = config.instanceName || os.hostname();
    const targetServerUrl = config.serverUrl || schedulerBaseUrl;
    const request = {
        tenantId: config.tenantId,
        userKey: config.userKey,
        instanceName,
        hostname: os.hostname(),
        virtualIp: config.registerIp || config.virtualIp,
        runtimeBridgeBaseUrl: resolveRuntimeBridgeBaseUrl(config),
        connectionKey: config.connectionKey,
        workspacePath: config.workspacePath,
        projectName: config.projectName,
        roleName: config.roleName,
    };
    logger.info(`[AutoRegister] 正在注册实例: ${instanceName}`);
    logger.info(`[AutoRegister] 调度中心: ${targetServerUrl}`);
    logger.info(`[AutoRegister] 用户 Key: ${config.userKey ? "****" + config.userKey.slice(-4) : "(未设置)"}`);
    logger.info(`[AutoRegister] 租户 ID: ${config.tenantId || "(自动推导)"}`);
    const response = await axios.post(`${targetServerUrl}/api/instances/register`, request, {
        headers: {
            "Content-Type": "application/json",
        },
        timeout: 10000,
    });
    return response.data;
}
/**
 * 执行注销请求
 */
async function doUnregister(instanceId) {
    const targetServerUrl = resolveLifecycleSchedulerBaseUrl(loadPrimaryLifecycleConfig(), instanceId);
    const binding = loadRuntimeBinding();
    const runtimeAccessToken = getRuntimeAccessToken(binding.userId, targetServerUrl);
    if (!runtimeAccessToken) {
        throw new Error("runtimeAccessToken is required to unregister bridge instance");
    }
    const response = await axios.post(`${targetServerUrl}/api/instances/unregister`, { instanceId }, {
        headers: {
            "Content-Type": "application/json",
            "X-Runtime-Token": runtimeAccessToken,
        },
        timeout: 10000,
    });
    return response.data;
}
/**
 * 自动注册主函数
 *
 * 带重试机制的注册逻辑
 *
 * 配置来源（优先级从高到低）：
 * 1. 传入的 customConfig
 * 2. 环境变量
 * 3. ~/.aws-bridge/config.json 配置文件
 * 4. 默认值
 */
export async function autoRegister(customConfig) {
    const configs = customConfig
        ? [{ ...loadConfig(), ...customConfig }]
        : loadConfigs();
    if (configs.length > 1) {
        const results = await Promise.all(configs.map((config) => autoRegisterSingle(config)));
        return results.every(Boolean);
    }
    return autoRegisterSingle(configs[0] || loadConfig());
}
async function autoRegisterSingle(config) {
    // 检查是否启用
    if (!config.enabled) {
        logger.info("[AutoRegister] 自动注册未启用");
        logger.info("[AutoRegister] 要启用自动注册，请创建配置文件 ~/.aws-bridge/config.json 或设置环境变量 AWS_AUTO_REGISTER=true");
        return false;
    }
    // 验证必填字段（userKey 为必填，tenantId 现在可选）
    if (!config.userKey) {
        logger.error("[AutoRegister] 缺少用户 Key（在配置文件中设置 userKey 或设置环境变量 AWS_USER_KEY）");
        return false;
    }
    // tenantId 现在是可选的，如果没有提供，后端会根据 userKey 自动推导
    const maxRetries = config.maxRetries || 5;
    const retryInterval = config.retryInterval || 5000;
    // 重试循环
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            registrationState.lastAttempt = new Date();
            const response = await doRegister(config);
            if (response.success) {
                registrationState.registered = true;
                registrationState.instanceId = response.instanceId;
                if (response.instanceId) {
                    registrationState.registrations[config.serverUrl || schedulerBaseUrl] =
                        response.instanceId;
                }
                registrationState.error = undefined;
                logger.info(`[AutoRegister] ✓ 注册成功！`);
                logger.info(`[AutoRegister]   实例 ID: ${response.instanceId}`);
                logger.info(`[AutoRegister]   消息: ${response.message}`);
                logger.info(`[AutoRegister]   更新: ${response.isUpdate ? "是" : "否"}`);
                if (response.runtimeAccessToken) {
                    try {
                        saveRuntimeBinding({
                            accessToken: response.runtimeAccessToken,
                            instanceId: response.instanceId,
                            userId: response.userId,
                            schedulerBaseUrl: response.serverUrl || config.serverUrl || schedulerBaseUrl,
                        });
                        logger.info("[AutoRegister] 已保存调度中心下发的 runtime access token");
                    }
                    catch (error) {
                        const err = error;
                        logger.error(`[AutoRegister] 保存 runtime access token 失败: ${err.message}`);
                        registrationState.error = err.message;
                        return false;
                    }
                }
                else {
                    logger.warn("[AutoRegister] 注册响应未包含 runtime access token，MCP 将无法访问调度中心，请检查 server 的 bridge 实例 token 颁发逻辑");
                }
                return true;
            }
            else {
                logger.warn(`[AutoRegister] 注册失败: ${response.message}`);
                registrationState.error = response.message;
            }
        }
        catch (error) {
            const err = error;
            const message = err.response?.data
                ? JSON.stringify(err.response.data)
                : err.message;
            logger.error(`[AutoRegister] 注册请求失败 (尝试 ${attempt}/${maxRetries}): ${message}`);
            registrationState.error = message;
        }
        // 如果不是最后一次尝试，等待后重试
        if (attempt < maxRetries) {
            logger.info(`[AutoRegister] ${retryInterval / 1000} 秒后重试...`);
            await new Promise((resolve) => setTimeout(resolve, retryInterval));
        }
    }
    logger.error(`[AutoRegister] ✗ 注册失败，已达最大重试次数`);
    logger.error(`[AutoRegister] ========================================`);
    logger.error(`[AutoRegister] 自动注册已启用但注册失败，实例无法正常工作`);
    logger.error(`[AutoRegister] 请检查以下配置：`);
    logger.error(`[AutoRegister]   - 用户 Key (userKey): ${config.userKey ? "****" + config.userKey.slice(-4) : "(未设置)"}`);
    logger.error(`[AutoRegister]   - 租户 ID (tenantId): ${config.tenantId || "(可选，将自动推导)"}`);
    logger.error(`[AutoRegister]   - 实例名 (instanceName): ${config.instanceName || "(使用主机名)"}`);
    logger.error(`[AutoRegister]   - 调度中心地址: ${config.serverUrl || schedulerBaseUrl}`);
    logger.error(`[AutoRegister]   - 最后错误: ${registrationState.error || "未知"}`);
    logger.error(`[AutoRegister] ========================================`);
    logger.error(`[AutoRegister] 配置来源：~/.aws-bridge/config.json 或环境变量`);
    return false;
}
/**
 * 注销实例
 */
export async function requestRuntimeAccessTokenRefresh() {
    const config = loadPrimaryLifecycleConfig();
    if (!config.userKey) {
        return {
            success: false,
            error: "userKey is required for runtime token refresh",
        };
    }
    const state = getRuntimeBindingPublicState();
    const targetServerUrl = resolveLifecycleSchedulerBaseUrl(config);
    const localIp = getLocalIpAddress(targetServerUrl);
    const runtimeBridgePort = process.env.AWS_RUNTIME_BRIDGE_PORT || 18081;
    const runtimeBridgeBaseUrl = `http://${config.registerIp || config.virtualIp || localIp}:${runtimeBridgePort}`;
    try {
        const response = await axios.post(`${targetServerUrl}/api/instances/runtime-tokens/refresh`, {
            tenantId: config.tenantId,
            userKey: config.userKey,
            instanceId: state.instanceId,
            instanceName: config.instanceName,
            runtimeBridgeBaseUrl,
        }, {
            headers: {
                "Content-Type": "application/json",
            },
            timeout: 10000,
        });
        if (!response.data.success || !response.data.runtimeAccessToken) {
            return {
                success: false,
                error: response.data.message ||
                    "scheduler did not return runtimeAccessToken",
            };
        }
        const previousToken = getRuntimeAccessToken();
        const updated = previousToken !== response.data.runtimeAccessToken;
        saveRuntimeBinding({
            accessToken: response.data.runtimeAccessToken,
            instanceId: state.instanceId,
            userId: response.data.userId || config.userKey,
            schedulerBaseUrl: targetServerUrl,
        });
        return {
            success: true,
            runtimeAccessToken: response.data.runtimeAccessToken,
            updated,
        };
    }
    catch (error) {
        const err = error;
        const message = err.response?.data
            ? JSON.stringify(err.response.data)
            : err.message;
        return { success: false, error: message };
    }
}
export async function requestRuntimeAccessTokenRefreshForServer(serverBaseUrl) {
    const targetServerUrl = normalizeSchedulerHttpBaseUrl(serverBaseUrl);
    if (!targetServerUrl) {
        return { success: false, error: "serverUrl is required for runtime token refresh" };
    }
    const config = loadConfigs().find((item) => normalizeSchedulerHttpBaseUrl(item.serverUrl) === targetServerUrl) || loadPrimaryLifecycleConfig();
    if (!config.userKey) {
        return {
            success: false,
            error: "userKey is required for runtime token refresh",
        };
    }
    const state = getRuntimeBindingPublicState();
    const localIp = getLocalIpAddress(targetServerUrl);
    const runtimeBridgePort = process.env.AWS_RUNTIME_BRIDGE_PORT || 18081;
    const runtimeBridgeBaseUrl = `http://${config.registerIp || config.virtualIp || localIp}:${runtimeBridgePort}`;
    try {
        const response = await axios.post(`${targetServerUrl}/api/instances/runtime-tokens/refresh`, {
            tenantId: config.tenantId,
            userKey: config.userKey,
            instanceId: state.instanceId,
            instanceName: config.instanceName,
            runtimeBridgeBaseUrl,
        }, {
            headers: {
                "Content-Type": "application/json",
            },
            timeout: 10000,
        });
        if (!response.data.success || !response.data.runtimeAccessToken) {
            return {
                success: false,
                error: response.data.message ||
                    "scheduler did not return runtimeAccessToken",
            };
        }
        const userId = response.data.userId || config.userKey;
        const previousToken = getRuntimeAccessToken(userId, targetServerUrl);
        const updated = previousToken !== response.data.runtimeAccessToken;
        saveScopedRuntimeAccessToken({
            userId,
            serverBaseUrl: targetServerUrl,
            accessToken: response.data.runtimeAccessToken,
        });
        return {
            success: true,
            runtimeAccessToken: response.data.runtimeAccessToken,
            updated,
        };
    }
    catch (error) {
        const err = error;
        const message = err.response?.data
            ? JSON.stringify(err.response.data)
            : err.message;
        return { success: false, error: message };
    }
}
export async function unregister() {
    if (!registrationState.registered || !registrationState.instanceId) {
        logger.info("[AutoRegister] 实例未注册，无需注销");
        return true;
    }
    try {
        const response = await doUnregister(registrationState.instanceId);
        if (response.success) {
            logger.info(`[AutoRegister] ✓ 注销成功: ${registrationState.instanceId}`);
            const targetServerUrl = resolveLifecycleSchedulerBaseUrl(loadPrimaryLifecycleConfig(), registrationState.instanceId);
            const binding = loadRuntimeBinding();
            if (binding.userId) {
                clearScopedRuntimeAccessToken(binding.userId, targetServerUrl);
            }
            clearRuntimeBinding();
            registrationState.registered = false;
            registrationState.instanceId = undefined;
            return true;
        }
        else {
            logger.warn(`[AutoRegister] 注销失败: ${response.message}`);
            return false;
        }
    }
    catch (error) {
        const err = error;
        logger.error(`[AutoRegister] 注销请求失败: ${err.message}`);
        return false;
    }
}
/**
 * 获取注册状态
 */
export function getRegistrationState() {
    return { ...registrationState };
}
/**
 * 检查是否已注册
 */
export function isRegistered() {
    return registrationState.registered;
}
/**
 * 获取实例 ID
 */
export function getInstanceId() {
    return registrationState.instanceId;
}
/**
 * ★★★ Bridge 重启清理
 *
 * 当 aws-runtime-bridge 重启时调用，通知调度中心将该 bridge 关联的所有 Agent 设置为离线。
 *
 * 清理逻辑：
 * 1. 调用调度中心的 /api/instances/bridge-restart-cleanup 接口
 * 2. 传入 instanceId 或 runtimeBridgeBaseUrl
 * 3. 调度中心会将关联的 Agent 设置为 is_online=false, runtime_status='stopped'
 *
 * @returns 清理结果
 */
export async function bridgeRestartCleanup() {
    const config = loadPrimaryLifecycleConfig();
    const instanceId = registrationState.instanceId;
    const targetServerUrl = resolveLifecycleSchedulerBaseUrl(config, instanceId);
    // 构建清理请求
    const requestBody = {};
    if (instanceId) {
        requestBody.instanceId = instanceId;
    }
    // 如果有配置，也传入 runtimeBridgeBaseUrl
    if (config.enabled) {
        const localIp = getLocalIpAddress(targetServerUrl);
        const port = process.env.AWS_RUNTIME_BRIDGE_PORT || 18081;
        requestBody.runtimeBridgeBaseUrl = `http://${config.registerIp || config.virtualIp || localIp}:${port}`;
    }
    if (!requestBody.instanceId && !requestBody.runtimeBridgeBaseUrl) {
        logger.info("[AutoRegister] Bridge 重启清理：没有 instanceId 或 runtimeBridgeBaseUrl，跳过清理");
        return { success: true, agentCount: 0 };
    }
    try {
        logger.info(`[AutoRegister] Bridge 重启清理：正在通知调度中心...`);
        logger.info(`[AutoRegister]   instanceId: ${requestBody.instanceId || "(无)"}`);
        logger.info(`[AutoRegister]   runtimeBridgeBaseUrl: ${requestBody.runtimeBridgeBaseUrl || "(无)"}`);
        const response = await axios.post(`${targetServerUrl}/api/instances/bridge-restart-cleanup`, requestBody, {
            headers: {
                "Content-Type": "application/json",
            },
            timeout: 10000,
        });
        if (response.data.success) {
            logger.info(`[AutoRegister] ✓ Bridge 重启清理成功：${response.data.message}`);
            logger.info(`[AutoRegister]   清理了 ${response.data.agentCount || 0} 个 Agent`);
            return { success: true, agentCount: response.data.agentCount || 0 };
        }
        else {
            logger.warn(`[AutoRegister] Bridge 重启清理失败：${response.data.message}`);
            return { success: false, error: response.data.message };
        }
    }
    catch (error) {
        const err = error;
        const message = err.response?.data
            ? JSON.stringify(err.response.data)
            : err.message;
        logger.warn(`[AutoRegister] Bridge 重启清理请求失败：${message}`);
        return { success: false, error: message };
    }
}
