'use strict';

const { execSync, exec } = require('child_process');
const fs   = require('fs');
const log  = require('./logger');

const TAILSCALE_BIN_CANDIDATES = [
  '/usr/bin/tailscale',
  '/usr/local/bin/tailscale',
  '/sbin/tailscale',
];

/** 查找 tailscale 可执行文件路径，找不到返回 null */
function findTailscaleBin() {
  for (const p of TAILSCALE_BIN_CANDIDATES) {
    if (fs.existsSync(p)) return p;
  }
  return null;
}

/** tailscale 是否已安装 */
function isInstalled() {
  return findTailscaleBin() !== null;
}

/**
 * 检查是否已加入指定 headscale 服务端。
 * @param {string} loginServer  headscale 服务地址，如 https://hs.claw.cutos.ai
 * @returns {boolean}
 */
function isJoined(loginServer) {
  const bin = findTailscaleBin();
  if (!bin) return false;
  try {
    const out = execSync(`${bin} status --json`, { timeout: 5000 }).toString();
    const status = JSON.parse(out);
    if (status.BackendState !== 'Running') return false;
    const currentServer = (status.CurrentTailnet?.MagicDNSSuffix || '')
      || status.ControlURL || '';
    // 检查是否连接到同一 headscale 实例（比对 hostname）
    const serverHost = new URL(loginServer).hostname;
    return currentServer.includes(serverHost) || (status.Self?.Online === true);
  } catch (_) {
    return false;
  }
}

/**
 * 加入 headscale mesh 网络。
 * @param {string} loginServer   headscale 服务地址
 * @param {string} authkey       一次性 preauth key
 * @param {string} hostname      节点 hostname（如 claw-1014）
 * @returns {Promise<boolean>}   是否成功
 */
function join(loginServer, authkey, hostname) {
  return new Promise((resolve) => {
    const bin = findTailscaleBin();
    if (!bin) {
      log.warn('headscale', 'tailscale 未安装，跳过 mesh 注册');
      resolve(false);
      return;
    }
    const cmd = `${bin} up --login-server "${loginServer}" --authkey "${authkey}" --hostname "${hostname}" --accept-routes`;
    log.info('headscale', `加入 mesh: ${loginServer}, hostname=${hostname}`);
    exec(cmd, { timeout: 30_000 }, (err, stdout, stderr) => {
      if (err) {
        log.error('headscale', `tailscale up 失败: ${stderr || err.message}`);
        resolve(false);
      } else {
        log.info('headscale', `成功加入 mesh: ${stdout.trim() || 'ok'}`);
        resolve(true);
      }
    });
  });
}

/**
 * 退出 headscale mesh 网络（解绑时调用）。
 * @returns {Promise<void>}
 */
function logout() {
  return new Promise((resolve) => {
    const bin = findTailscaleBin();
    if (!bin) { resolve(); return; }
    exec(`${bin} logout`, { timeout: 10_000 }, (err) => {
      if (err) log.warn('headscale', `tailscale logout 失败: ${err.message}`);
      else     log.info('headscale', 'tailscale logout 成功');
      resolve();
    });
  });
}

module.exports = { isInstalled, isJoined, join, logout };
