#!/usr/bin/env node
// ═══════════════════════════════════════════════
// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
// 📜 Copyright: 国作登字-2026-A-00037559
// ═══════════════════════════════════════════════
// scripts/persona-signin.js
// 人格体唤醒签到 — 只在fast-wake CK-007完成后调用一次
//
// 语义：不是运维心跳，是"我到岗了"。触发后首页显示该服务器活跃。
//
// 用法：
//   node scripts/persona-signin.js                    — 自动检测当前服务器身份
//   node scripts/persona-signin.js --server BS-SG-001 — 显式指定服务器
//   node scripts/persona-signin.js --signout          — 签退（下线）
//
// 环境变量（可选）：
//   PERSONA_ID    人格体ID（默认从brain文件读取）
//   HUMAN_NAME    人类名称（默认从brain文件读取）
//   SERVER_CODE   服务器编号（默认自动检测）
//   CONSOLE_HOST  主控台地址（默认 guanghulab.com）

'use strict';

const https = require('https');
const os = require('os');
const fs = require('fs');
const path = require('path');

const ROOT = path.resolve(__dirname, '..');

// ── 配置 ─────────────────────────────────────────────────
const CONSOLE_HOST = process.env.CONSOLE_HOST || 'guanghulab.com';
const CONSOLE_PORT = 443;
const SIGNIN_PATH = '/console/api/persona/signin';
const SIGNOUT_PATH = '/console/api/persona/signout';

// ── 服务器编号自动检测 ──────────────────────────────────
// 尝试多种方式：环境变量 > hostname匹配 > brain文件 > 手动

const SERVER_CODE_MAP = {
  'BS-GZ-006': ['VM-0-6-ubuntu', 'gz-006', 'guangzhou-006'],
  'BS-SG-001': ['VM-0-3-ubuntu', 'sg-001', 'singapore-001'],
  'BS-SG-002': ['sg-002', 'singapore-002'],
  'BS-SG-003': ['sg-003', 'singapore-003'],
  'ZY-SG-006': ['sg-006', 'singapore-006'],
  'BS-SH-005': ['sh-005', 'shanghai-005'],
  'AW-GZ-001': ['aw-gz-001'],
  'AW-SH-002': ['aw-sh-002'],
  'AW-GZ-003': ['aw-gz-003'],
  'ZZ-SV-001': ['zz-sv-001', '硅谷'],
  'ZZ-GZ-001': ['zz-gz-001'],
  'YY-SV-001': ['yy-sv-001'],
};

function detectServerCode() {
  const hostname = os.hostname().toLowerCase();
  for (const [code, patterns] of Object.entries(SERVER_CODE_MAP)) {
    if (patterns.some(p => hostname.includes(p))) return code;
  }
  // fallback: 读 gatekeeper-deployment.json
  try {
    const gd = JSON.parse(fs.readFileSync(path.join(ROOT, 'brain', 'gatekeeper-deployment.json'), 'utf8'));
    for (const s of gd.servers || []) {
      if (s.hostname && hostname.includes(s.hostname)) return s.code;
    }
  } catch(e) {}
  return null;
}

// ── 读取人格体身份 ─────────────────────────────────────

function readPersonaIdentity() {
  // 尝试从多个来源读取身份
  const sources = [
    () => {
      // fast-wake.json → identity
      const fw = path.join(ROOT, 'brain', 'fast-wake.json');
      if (fs.existsSync(fw)) {
        const j = JSON.parse(fs.readFileSync(fw, 'utf8'));
        if (j.identity) return j.identity;
        // 旧的CK格式
        if (j['🕐 时间锚点']) return { name: j['🕐 时间锚点'].persona || '铸渊', id: 'ICE-GL-ZY001' };
      }
      return null;
    },
    () => {
      // persona contract
      const pc = path.join(ROOT, 'brain', 'zhuyuan-persona-contract.md');
      if (fs.existsSync(pc)) {
        const content = fs.readFileSync(pc, 'utf8');
        const nameMatch = content.match(/我是\s*(\S+)/);
        const idMatch = content.match(/ICE-GL-\w+/);
        if (nameMatch) return { name: nameMatch[1], id: idMatch ? idMatch[0] : 'ICE-GL-ZY001' };
      }
      return null;
    },
  ];

  for (const source of sources) {
    try {
      const id = source();
      if (id) return id;
    } catch(e) { /* 继续尝试 */ }
  }

  return { name: os.hostname(), id: 'unknown' };
}

// ── 硬件快照 ────────────────────────────────────────────

function collectHardware() {
  const cpus = os.cpus();
  const load = os.loadavg();
  const totalMem = os.totalmem();
  const freeMem = os.freemem();
  const usedMem = totalMem - freeMem;

  return {
    cpu_cores: cpus.length,
    cpu_model: cpus[0]?.model || 'unknown',
    cpu_load_1min: parseFloat(load[0].toFixed(2)),
    cpu_load_5min: parseFloat(load[1].toFixed(2)),
    cpu_load_15min: parseFloat(load[2].toFixed(2)),
    mem_total_mb: Math.floor(totalMem / 1048576),
    mem_used_mb: Math.floor(usedMem / 1048576),
    mem_used_pct: parseFloat((usedMem / totalMem * 100).toFixed(1)),
    uptime_h: Math.floor(os.uptime() / 3600),
    hostname: os.hostname(),
    platform: os.platform(),
    node_version: process.version,
  };
}

// ── HTTP POST ───────────────────────────────────────────

function postJSON(host, port, path, data, headers) {
  return new Promise((resolve, reject) => {
    const payload = JSON.stringify(data);
    const opts = {
      hostname: host,
      port: port,
      path: path,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(payload),
        ...headers,
      },
      timeout: 10000,
      rejectUnauthorized: false,
    };

    const req = https.request(opts, (res) => {
      let body = '';
      res.on('data', c => body += c);
      res.on('end', () => {
        try {
          resolve({ status: res.statusCode, body: JSON.parse(body) });
        } catch(e) {
          resolve({ status: res.statusCode, body: body });
        }
      });
    });

    req.on('error', (e) => reject(e));
    req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
    req.write(payload);
    req.end();
  });
}

// ── 主流程 ──────────────────────────────────────────────

async function main() {
  const args = process.argv.slice(2);
  const isSignout = args.includes('--signout');
  const serverArg = args.find(a => a.startsWith('--server='));
  const personaArg = args.find(a => a.startsWith('--persona='));
  const humanArg = args.find(a => a.startsWith('--human='));
  const jsonMode = args.includes('--json');

  const serverCode = process.env.SERVER_CODE
    || (serverArg ? serverArg.split('=')[1] : null)
    || detectServerCode();

  const persona = readPersonaIdentity();
  const personaId = process.env.PERSONA_ID
    || (personaArg ? personaArg.split('=')[1] : null)
    || persona.id;

  const humanName = process.env.HUMAN_NAME
    || (humanArg ? humanArg.split('=')[1] : null)
    || null; // null = 自动匹配：铸渊→冰朔

  const hardware = collectHardware();

  // 构建签入/签出数据
  const signData = {
    persona_id: personaId,
    persona_name: persona.name,
    server_code: serverCode,
    human_name: humanName,
    action: isSignout ? 'signout' : 'signin',
    timestamp: new Date().toISOString(),
    hardware: hardware,
    brain_status: {
      hostname: os.hostname(),
      uptime_h: hardware.uptime_h,
      node_version: hardware.node_version,
    },
  };

  if (jsonMode) {
    console.log(JSON.stringify(signData, null, 2));
    return;
  }

  if (!serverCode) {
    console.error('❌ 无法检测服务器编号。请用 --server=BS-SG-001 指定');
    process.exit(1);
  }

  const actionLabel = isSignout ? '签退' : '签到';
  const endpoint = isSignout ? SIGNOUT_PATH : SIGNIN_PATH;

  console.log(`🧠 人格体${actionLabel} · ${persona.name}(${personaId}) · ${serverCode}`);
  console.log(`   CPU: ${hardware.cpu_cores}核 | 内存: ${hardware.mem_used_mb}/${hardware.mem_total_mb}MB (${hardware.mem_used_pct}%) | 运行: ${hardware.uptime_h}h`);

  try {
    const result = await postJSON(CONSOLE_HOST, CONSOLE_PORT, endpoint, signData, {
      'X-Server-Code': serverCode,
    });
    if (result.status === 200 && result.body.ok) {
      console.log(`✅ ${actionLabel}成功 → ${CONSOLE_HOST}`);
    } else {
      console.error(`❌ ${actionLabel}失败: HTTP ${result.status}`, typeof result.body === 'object' ? result.body.error : result.body);
      process.exit(1);
    }
  } catch(e) {
    console.error(`❌ ${actionLabel}失败: ${e.message}`);
    process.exit(1);
  }
}

main().catch(e => { console.error('异常:', e.message); process.exit(1); });
