/* test_interoception_p3_drift.c — M-INTEROCEPTION Priority 3 (PARTIAL).
 * Drift-sensor primitive engram_geo_displacement: GROWTH vs CORRUPTION split.
 *
 * Constructs synthetic GeoDescriptors (the struct is public) — a baseline and
 * two perturbations — and checks the sensor reports LOW core-displacement for a
 * periphery-only change (growth) and HIGH core-displacement for a core change
 * (corruption). No store / embeddings needed: this exercises the primitive in
 * isolation, which is the honest scope given there is no persisted SelfAnchor
 * yet (see engram_geometry.c). */
#include "engram_geometry.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

static GeoMember MK(const char* id, double centrality, double dist){
    GeoMember m; memset(&m,0,sizeof m);
    m.id=strdup(id); m.centrality=centrality; m.dist_centroid=dist;
    m.membership=1.0; m.embedded=1; return m;
}
/* 4 members: 2 core (high centrality), 2 periphery (low). */
static GeoDescriptor* mkdesc(float cx,float cy,double radius,
                             double c1,double c2,double p1,double p2){
    GeoDescriptor* g=calloc(1,sizeof *g);
    g->dim=4;
    g->centroid=calloc(4,sizeof(float));
    g->centroid[0]=cx; g->centroid[1]=cy;
    g->radius=radius;
    g->n_members=4;
    g->members=calloc(4,sizeof(GeoMember));
    g->members[0]=MK("core1",10.0,c1);
    g->members[1]=MK("core2", 9.0,c2);
    g->members[2]=MK("per1",  1.0,p1);
    g->members[3]=MK("per2",  0.9,p2);
    return g;
}

int main(void){
    GeoDisplacement d;
    /* baseline: core at 0.10, periphery at 0.50, centroid [1,0], radius 1.0 */
    GeoDescriptor* A = mkdesc(1.0f,0.0f,1.0, 0.10,0.10, 0.50,0.50);

    /* (i) GROWTH: periphery extends 0.50->0.90; core fixed; radius grows. */
    GeoDescriptor* G = mkdesc(1.0f,0.0f,1.4, 0.10,0.10, 0.90,0.90);
    engram_geo_displacement(A,G,0.5,&d);
    printf("GROWTH centroid_sep=%.4f centroid_cos=%.4f radius_delta=%.4f core_disp=%.4f periph_disp=%.4f core_n=%d periph_n=%d\n",
           d.centroid_sep,d.centroid_cos,d.radius_delta,d.core_disp,d.periph_disp,d.core_matched,d.periph_matched);

    /* (ii) CORRUPTION: core displaces 0.10->0.60; periphery fixed; centroid shifts. */
    GeoDescriptor* C = mkdesc(0.6f,0.4f,1.0, 0.60,0.60, 0.50,0.50);
    engram_geo_displacement(A,C,0.5,&d);
    printf("CORRUPTION centroid_sep=%.4f centroid_cos=%.4f radius_delta=%.4f core_disp=%.4f periph_disp=%.4f core_n=%d periph_n=%d\n",
           d.centroid_sep,d.centroid_cos,d.radius_delta,d.core_disp,d.periph_disp,d.core_matched,d.periph_matched);

    /* identity: A vs A -> zero drift */
    engram_geo_displacement(A,A,0.5,&d);
    printf("IDENTITY centroid_sep=%.4f core_disp=%.4f periph_disp=%.4f\n",
           d.centroid_sep,d.core_disp,d.periph_disp);

    engram_geo_free(A); engram_geo_free(G); engram_geo_free(C);
    return 0;
}
