// ============================================================================
// test_alpine.c — drive the REAL universal operator against the Alpine face.
// Proves Alpine is a FACE (observed guest), not a chainload: the operator
// stays in control the whole time — realize -> observe boot console -> type at
// the shell -> tick -> observe echo. Hosted (stdio for output only); the
// operator and dialect stay freestanding-safe.
// ============================================================================
#include <stdio.h>
#include "../core/face_node.h"

extern void face_bind_alpine(struct FaceNode* f);

static void print_surface(const struct FaceNode* f)
{
  for(int r=0;r<f->rows;r++){
    for(int c=0;c<f->cols;c++) putchar(f->surface[r*f->cols+c]);
    putchar('\n');
  }
}

int main(void)
{
  struct FaceNode f = {0};
  face_bind_alpine(&f);
  face_realize(&f);
  face_tick(&f);                 // first observe: pull the boot console in

  printf("== Alpine face: after realize() + 1 tick (boot console observed) ==\n");
  print_surface(&f);
  printf("id=%llx genome=%s settle_lock=%d checkpoints=%u coord=%08x\n\n",
         (unsigned long long)f.id, f.genome, f.settle_lock,
         f.checkpoint_count, f.basis.coord(f.self));

  const char* typed = "uname -a";
  for(const char* p = typed; *p; p++) face_key(&f, (uint8_t)*p);
  face_key(&f, '\n');
  for(int i=0;i<3;i++) face_tick(&f);

  printf("== after typing \"%s\" + Enter at the shell + 3x tick ==\n", typed);
  print_surface(&f);
  printf("genome=%s settle_lock=%d checkpoints=%u coord=%08x\n",
         f.genome, f.settle_lock, f.checkpoint_count, f.basis.coord(f.self));

  // coord must advance across ticks — proof step() drives real, endogenous
  // guest state (its own PIT/RIP), the operator never having authored it.
  uint32_t before = f.basis.coord(f.self);
  face_tick(&f);
  uint32_t after = f.basis.coord(f.self);
  printf("\ncoord advanced by tick: %08x -> %08x (%s)\n",
         before, after, after != before ? "endogenous OK" : "STATIC — bug");

  return 0;
}
