<?php
require __DIR__ . '/../iris-pi-common/_common.php';
require_login();

$name = $_GET['name'] ?? '';
$vm = find_vm($name);
if (!$vm) { http_response_code(404); echo "VM not found"; exit; }

$evts = db()->prepare('SELECT * FROM events WHERE vm_name = ? ORDER BY id DESC LIMIT 200');
$evts->execute([$name]);
$events = $evts->fetchAll();

$profile = find_profile($vm['profile_slug']);
$site = find_site($vm['esx_site_code']);

$page = 'vms';
$page_title = $name;
require __DIR__ . '/_header.php';
?>

<style>
.grid2 { display:grid; grid-template-columns: 1fr 1fr; gap:20px; }
dl { display:grid; grid-template-columns: 130px 1fr; gap:8px 14px; margin:0; }
dt { color:var(--muted); }
dd { margin:0; }
.timeline { font-size:12px; }
.timeline .evt { display:grid; grid-template-columns: 140px 140px 1fr; gap:12px; padding:6px 0; border-bottom:1px solid #21262d; }
.timeline .evt:last-child { border-bottom:none; }
.timeline .ts { color:var(--muted); }
.timeline .kind { color:var(--accent); }
</style>

<div style="margin-bottom:16px;display:flex;justify-content:space-between;align-items:center">
  <a href="index.php" class="muted">← retour à la liste</a>
  <span id="live-status" data-state="loading">● connecting...</span>
</div>

<div class="grid2">
  <div>
    <div class="panel">
      <div class="panel-header"><h2>État</h2></div>
      <div class="panel-body" id="vm-state-body">
        <dl>
          <dt>Status</dt>     <dd><span id="rt-status" class="badge b-<?= h($vm['status']) ?>"><?= h($vm['status']) ?></span></dd>
          <dt>Demandé</dt>    <dd><?= date('d/m/Y H:i:s', $vm['requested_at']) ?></dd>
          <dt>Démarré</dt>    <dd id="rt-started"><?= $vm['started_at'] ? date('d/m/Y H:i:s', $vm['started_at']) : '—' ?></dd>
          <dt>Prêt</dt>       <dd id="rt-ready"><?= $vm['ready_at'] ? date('d/m/Y H:i:s', $vm['ready_at']) : '—' ?></dd>
          <dt>Last seen</dt>  <dd id="rt-last-seen"><?= $vm['last_seen_at'] ? date('d/m/Y H:i:s', $vm['last_seen_at']) : '—' ?></dd>
          <dt>Last msg</dt>   <dd class="muted" id="rt-last-msg"><?= h($vm['last_message'] ?? '—') ?></dd>
        </dl>
      </div>
    </div>

    <div class="panel">
      <div class="panel-header"><h2>Runtime (live)</h2></div>
      <div class="panel-body">
        <p class="muted" id="runtime-empty">En attente du premier heartbeat…</p>
        <dl id="runtime-dl" style="display:none">
          <dt>Liveness</dt>   <dd><span id="rt-liveness" class="liveness-unknown">—</span></dd>
          <dt>Last HB</dt>    <dd><span id="rt-hb-age">—</span></dd>
          <dt>Uptime</dt>     <dd id="rt-uptime">—</dd>
          <dt>Load 1m</dt>    <dd id="rt-load">—</dd>
          <dt>CPU</dt>        <dd id="rt-cpu">—</dd>
          <dt>RAM</dt>        <dd id="rt-mem">—</dd>
          <dt>Disque /</dt>   <dd id="rt-disk">—</dd>
          <dt>IP primaire</dt><dd id="rt-ip">—</dd>
          <dt>Interfaces</dt> <dd id="rt-ifaces" style="font-size:11px">—</dd>
          <dt>Agents</dt>     <dd id="rt-agents" style="font-size:11px">—</dd>
        </dl>
      </div>
    </div>

    <div class="panel">
      <div class="panel-header"><h2>Identité IRIS (node.conf)</h2></div>
      <div class="panel-body">
        <dl>
          <dt>Hostname</dt> <dd><code><?= h($vm['name']) ?></code></dd>
          <dt>FQDN</dt>     <dd><code><?= h($vm['name']) ?>.<?= h($site['domain'] ?? 'iris.local') ?></code></dd>
          <dt>Site</dt>     <dd><?= h($vm['esx_site_code']) ?></dd>
          <dt>Network</dt>  <dd><?= h($vm['range_name']) ?></dd>
          <dt>Segment</dt>  <dd><?= h($vm['segment']) ?></dd>
          <dt>Role</dt>     <dd><strong><?= h($vm['iris_role']) ?></strong></dd>
          <dt>IP</dt>       <dd><code><?= h($vm['primary_ip']) ?></code></dd>
        </dl>
      </div>
    </div>

    <div class="panel">
      <div class="panel-header"><h2>Ressources ESX</h2></div>
      <div class="panel-body">
        <dl>
          <dt>Profile</dt>    <dd><?= h($profile['slug']) ?> — <?= h($profile['label']) ?></dd>
          <dt>CPU/RAM</dt>    <dd><?= $profile['cpu'] ?> vCPU / <?= $profile['ram_mb'] ?> MB</dd>
          <dt>Disque</dt>     <dd><?= $profile['disk_gb'] ?> GB</dd>
          <dt>NICs</dt>       <dd><?= $profile['nic_count'] ?></dd>
          <dt>ESX host</dt>   <dd><code><?= h($vm['esx_code']) ?></code> (<?= h($vm['esx_fqdn']) ?>)</dd>
          <dt>Datastore</dt>  <dd><?= h($vm['datastore_default']) ?></dd>
          <dt>Folder</dt>     <dd><code><?= h($vm['folder_root']) ?>/<?= h($vm['range_name']) ?>/<?= h($vm['name']) ?></code></dd>
          <dt>Portgroup</dt>  <dd><code><?= h($vm['portgroup']) ?></code></dd>
          <dt>VLAN ID</dt>    <dd><?= h((string)$vm['vlan_id']) ?></dd>
          <dt>CIDR</dt>       <dd><code><?= h($vm['cidr']) ?></code></dd>
          <dt>Gateway</dt>    <dd><code><?= h($vm['gateway']) ?></code></dd>
        </dl>
      </div>
    </div>

        <div class="panel">
      <div class="panel-header"><h2>Ligne de boot kernel (à coller au menu Debian)</h2></div>
      <div class="panel-body" style="font-size:12px">
        <p class="muted" style="margin-top:0">
          Au menu Debian de l'installeur, tape <code>Tab</code> sur "Install"
          (ou <code>e</code> en UEFI) et ajoute cette ligne complète à la
          fin des paramètres kernel. Les paramètres réseau sont injectés
          directement pour que l'install marche même sans DHCP (DMZ) et
          que le hostname soit posé dès le boot.
        </p>
<?php
[$net_addr, $cidr_bits] = explode('/', $vm['cidr']);
$netmask = long2ip(-1 << (32 - (int)$cidr_bits));
$boot_line = sprintf(
    'auto=true priority=critical hostname=%s domain=%s interface=auto netcfg/disable_autoconfig=true netcfg/get_ipaddress=%s netcfg/get_netmask=%s netcfg/get_gateway=%s netcfg/get_nameservers="%s" netcfg/confirm_static=true url=%s/preseed.php?name=%s',
    $vm['name'],
    $site['domain'] ?? 'iris.local',
    $vm['primary_ip'],
    $netmask,
    $vm['gateway'],
    $vm['dns'],
    VPS_BASE,
    $vm['name']
);
?>
        <div style="background:#0d1117;border:1px solid var(--accent);padding:14px;border-radius:4px;font-family:'IBM Plex Mono',monospace;color:var(--accent);word-break:break-all;font-size:11px;line-height:1.6;user-select:all" id="boot-line"><?= h($boot_line) ?></div>
        <div style="margin-top:10px;text-align:right">
          <button type="button" onclick="navigator.clipboard.writeText(document.getElementById('boot-line').textContent.trim()); this.textContent='✓ Copié'; setTimeout(()=>this.textContent='Copier la ligne', 2000);">Copier la ligne</button>
        </div>
      </div>
    </div>

    <div class="panel">
      <div class="panel-header"><h2>URLs servies pour cette VM</h2></div>
      <div class="panel-body" style="font-size:12px">
        <p class="muted" style="margin-top:0">Tu peux les ouvrir pour vérifier le contenu généré :</p>
        <ul style="margin:0;padding-left:20px;line-height:1.8">
          <li><a href="preseed.php?name=<?= urlencode($name) ?>" target="_blank">preseed.php</a></li>
          <li><a href="firstboot.sh.php?name=<?= urlencode($name) ?>" target="_blank">firstboot.sh</a></li>
          <li><a href="nodeconf.php?name=<?= urlencode($name) ?>" target="_blank">nodeconf.php</a></li>
        </ul>
      </div>
    </div>
  </div>

  <div>
    <div class="panel">
      <div class="panel-header"><h2>Timeline (<span id="tl-count"><?= count($events) ?></span>)</h2></div>
      <div class="panel-body">
        <div class="timeline" id="tl-body">
        <?php if (!$events): ?>
          <p class="muted">Aucun événement pour cette VM.</p>
        <?php else: ?>
        <?php foreach ($events as $e): ?>
          <div class="evt">
            <span class="ts"><?= date('d/m H:i:s', $e['created_at']) ?></span>
            <span class="kind"><?= h($e['kind']) ?></span>
            <span><?= h($e['message'] ?? '') ?></span>
          </div>
        <?php endforeach; ?>
        <?php endif; ?>
        </div>
      </div>
    </div>
  </div>
</div>

<script src="/iris/_autorefresh.js"></script>
<script>
const VM_NAME = <?= json_encode($name) ?>;

function renderTimeline(events) {
  const tl = document.getElementById('tl-body');
  if (!events || events.length === 0) {
    tl.innerHTML = '<p class="muted">Aucun événement pour cette VM.</p>';
    return;
  }
  tl.innerHTML = events.map(e => {
    const d = new Date(e.created_at * 1000);
    const ts = d.toLocaleDateString('fr-FR', {day:'2-digit', month:'2-digit'}) + ' ' +
               d.toLocaleTimeString('fr-FR');
    const msg = (e.message || '').replace(/[<>&"]/g, c => ({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]));
    const kind = (e.kind || '').replace(/[<>&"]/g, c => ({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]));
    return `<div class="evt"><span class="ts">${ts}</span><span class="kind">${kind}</span><span>${msg}</span></div>`;
  }).join('');
  document.getElementById('tl-count').textContent = events.length;
}

function renderRuntime(vm, now) {
  const empty = document.getElementById('runtime-empty');
  const dl = document.getElementById('runtime-dl');

  if (!vm.last_heartbeat) {
    empty.style.display = '';
    dl.style.display = 'none';
    return;
  }

  empty.style.display = 'none';
  dl.style.display = '';

  // Liveness
  const liv = document.getElementById('rt-liveness');
  liv.textContent = '● ' + vm.liveness;
  liv.className = 'liveness-' + vm.liveness;

  document.getElementById('rt-hb-age').textContent = IRIS.formatAge(vm.heartbeat_age_sec) + ' ago';
  document.getElementById('rt-uptime').textContent = IRIS.formatUptime(vm.uptime_sec);
  document.getElementById('rt-load').textContent = (vm.load_1m ?? 0).toFixed(2);

  // CPU with diff
  const cpuEl = document.getElementById('rt-cpu');
  if (vm.diffs && vm.diffs.cpu) {
    cpuEl.innerHTML = `<div class="diff-row">
      <span class="current">${vm.diffs.cpu.current}</span> vCPU
      (configuré : <span class="configured">${vm.diffs.cpu.configured}</span>)
    </div>`;
  } else {
    cpuEl.textContent = vm.cpu_count + ' vCPU';
  }

  // RAM with diff
  const memEl = document.getElementById('rt-mem');
  const memTotalMB = Math.round((vm.mem_total_kb || 0) / 1024);
  const memAvailMB = Math.round((vm.mem_avail_kb || 0) / 1024);
  const memText = `${memTotalMB} MB total · ${memAvailMB} MB libre`;
  if (vm.diffs && vm.diffs.ram_mb) {
    memEl.innerHTML = `<div class="diff-row">
      <span class="current">${vm.diffs.ram_mb.current} MB</span>
      (configuré : <span class="configured">${vm.diffs.ram_mb.configured} MB</span>)
    </div>`;
  } else {
    memEl.textContent = memText;
  }

  // Disk
  document.getElementById('rt-disk').textContent = vm.disk_root_used_pct + '% utilisé';

  // IP with diff
  const ipEl = document.getElementById('rt-ip');
  if (vm.diffs && vm.diffs.ip) {
    ipEl.innerHTML = `<div class="diff-row">
      <span class="current">${vm.diffs.ip.current}</span>
      (configuré : <span class="configured">${vm.diffs.ip.configured}</span>)
    </div>`;
  } else {
    ipEl.textContent = vm.ip_primary || '—';
  }

  // Interfaces
  const ifacesEl = document.getElementById('rt-ifaces');
  if (vm.interfaces && vm.interfaces.length > 0) {
    ifacesEl.innerHTML = vm.interfaces.map(i =>
      `<div><code>${i.name}</code> · ${i.mac || '—'} · ${(i.ipv4 || []).join(', ') || '—'}</div>`
    ).join('');
  } else {
    ifacesEl.textContent = '—';
  }

  // Agents
  const agentsEl = document.getElementById('rt-agents');
  if (vm.agents && Object.keys(vm.agents).length > 0) {
    agentsEl.innerHTML = Object.entries(vm.agents).map(([n, v]) =>
      `<div><code>${n}</code> v${v}</div>`
    ).join('');
  } else {
    agentsEl.textContent = '—';
  }
}

function renderState(vm) {
  document.getElementById('rt-status').textContent = vm.status;
  document.getElementById('rt-status').className = 'badge b-' + vm.status;

  const fmt = (ts) => ts ? new Date(ts * 1000).toLocaleString('fr-FR') : '—';
  document.getElementById('rt-started').textContent = fmt(vm.started_at);
  document.getElementById('rt-ready').textContent = fmt(vm.ready_at);
  document.getElementById('rt-last-seen').textContent = fmt(vm.last_seen);
  document.getElementById('rt-last-msg').textContent = vm.last_msg || '—';
}

IRIS.autoRefresh({
  endpoint: '/pi/api/vm-runtime.php?name=' + encodeURIComponent(VM_NAME) + '&with_events=1',
  interval: 5000,
  statusElement: '#live-status',
  onUpdate: (data) => {
    if (data.vm) {
      renderState(data.vm);
      renderRuntime(data.vm, data.now);
    }
    if (data.events) {
      renderTimeline(data.events);
    }
  }
});
</script>

<?php require __DIR__ . '/_footer.php'; ?>
