# SPDX-License-Identifier: LSL-1.0
# Copyright (c) 2026 Markus Maiwald
# Stewardship: Self Sovereign Society Foundation
#
# This file is part of the Nexus Sovereign Core.
# See legal/LICENSE_SOVEREIGN.md for license terms.

# SPEC-060: System Ontology - Nim Bindings
# Ground Zero Phase 2: Event System

## Event System Nim Bindings

# Kernel logging (freestanding-safe)
proc kprint(s: cstring) {.importc, cdecl.}
proc kprint_hex(n: uint64) {.importc, cdecl.}
proc kprintln(s: cstring) {.importc, cdecl.}

# Import STL from HAL
proc stl_init*() {.importc, cdecl.}
proc stl_emit*(
  kind: uint16,
  fiber_id: uint64,
  entity_id: uint64,
  cause_id: uint64,
  data0: uint64,
  data1: uint64,
  data2: uint64
): uint64 {.importc, cdecl.}
proc stl_lookup*(event_id: uint64): pointer {.importc, cdecl.}
proc stl_count*(): uint32 {.importc, cdecl.}

type
  QueryResult* = object
    count*: uint32
    events*: array[64, pointer]

proc stl_query_by_fiber*(fiber_id: uint64, result: var QueryResult) {.importc, cdecl.}
proc stl_query_by_kind*(kind: uint16, result: var QueryResult) {.importc, cdecl.}
proc stl_get_recent*(max_count: uint32, result: var QueryResult) {.importc, cdecl.}
proc stl_query_by_time_range*(start_ns: uint64, end_ns: uint64, result: var QueryResult) {.importc, cdecl.}

type
  LineageResult* = object
    count*: uint32
    event_ids*: array[16, uint64]

proc stl_trace_lineage*(event_id: uint64, result: var LineageResult) {.importc, cdecl.}

type
  SystemStats* = object
    total_events*: uint32
    boot_events*: uint32
    fiber_events*: uint32
    cap_events*: uint32
    io_events*: uint32
    mem_events*: uint32
    net_events*: uint32
    security_events*: uint32

proc stl_get_stats*(stats: var SystemStats) {.importc, cdecl.}
proc stl_export_binary*(dest: pointer, max_size: uint64): uint64 {.importc, cdecl.}

## Event Types (Mirror from ontology.zig)
type
  EventKind* = enum
    EvNull = 0
    # Lifecycle
    EvSystemBoot = 1
    EvSystemShutdown = 2
    EvFiberSpawn = 3
    EvFiberTerminate = 4
    # Capability
    EvCapabilityGrant = 10
    EvCapabilityRevoke = 11
    EvCapabilityDelegate = 12
    # I/O
    EvChannelOpen = 20
    EvChannelClose = 21
    EvChannelRead = 22
    EvChannelWrite = 23
    # Memory
    EvMemoryAllocate = 30
    EvMemoryFree = 31
    EvMemoryMap = 32
    # Network
    EvNetworkPacketRx = 40
    EvNetworkPacketTx = 41
    # Security
    EvAccessDenied = 50
    EvPolicyViolation = 51

## High-level API for kernel use

proc emit_system_boot*(): uint64 =
  ## Emit system boot event
  return stl_emit(
    uint16(EvSystemBoot),
    0,  # fiber_id (kernel)
    0,  # entity_id
    0,  # cause_id
    0, 0, 0  # data
  )

proc emit_fiber_spawn*(fiber_id: uint64, parent_id: uint64, cause_id: uint64 = 0): uint64 =
  ## Emit fiber spawn event
  return stl_emit(
    uint16(EvFiberSpawn),
    parent_id,
    fiber_id,
    cause_id,
    0, 0, 0
  )

proc emit_capability_grant*(
  fiber_id: uint64,
  cap_type: uint8,
  object_id: uint64,
  slot: uint32,
  cause_id: uint64 = 0
): uint64 =
  ## Emit capability grant event
  return stl_emit(
    uint16(EvCapabilityGrant),
    fiber_id,
    object_id,
    cause_id,
    uint64(cap_type),
    uint64(slot),
    0
  )

proc emit_channel_write*(
  fiber_id: uint64,
  channel_id: uint64,
  bytes_written: uint64,
  cause_id: uint64 = 0
): uint64 =
  ## Emit channel write event
  return stl_emit(
    uint16(EvChannelWrite),
    fiber_id,
    channel_id,
    cause_id,
    bytes_written,
    0, 0
  )

proc emit_access_denied*(
  fiber_id: uint64,
  resource_id: uint64,
  attempted_perm: uint8,
  cause_id: uint64 = 0
): uint64 =
  ## Emit access denied event (security)
  return stl_emit(
    uint16(EvAccessDenied),
    fiber_id,
    resource_id,
    cause_id,
    uint64(attempted_perm),
    0, 0
  )

## Initialization
proc init_stl_subsystem*() =
  ## Initialize the STL subsystem (call from kmain)
  stl_init()
  kprintln("[STL] System Truth Ledger initialized")

## Query API
proc stl_print_summary*() {.exportc, cdecl.} =
  ## Print a summary of the STL ledger to the console
  var stats: SystemStats
  stl_get_stats(stats)

  kprintln("\n[STL] System Truth Ledger Summary:")
  kprint("[STL]   Total Events:    "); kprint_hex(uint64(stats.total_events)); kprintln("")
  kprint("[STL]   Lifecycle:       "); kprint_hex(uint64(stats.boot_events + stats.fiber_events)); kprintln("")
  kprint("[STL]   Capabilities:    "); kprint_hex(uint64(stats.cap_events)); kprintln("")
  kprint("[STL]   I/O & Channels:  "); kprint_hex(uint64(stats.io_events)); kprintln("")
  kprint("[STL]   Memory:          "); kprint_hex(uint64(stats.mem_events)); kprintln("")
  kprint("[STL]   Security/Policy: "); kprint_hex(uint64(stats.security_events)); kprintln("")
  
  # Demonstrate Causal Graph for the last event
  if stats.total_events > 0:
    let last_id = uint64(stats.total_events - 1) 
    var lineage: LineageResult
    stl_trace_lineage(last_id, lineage)
    
    kprintln("\n[STL] Causal Graph Audit:");
    kprint("[STL]   Target: "); kprint_hex(last_id); kprintln("")
    
    for i in 0..<lineage.count:
      let eid = lineage.event_ids[i]
      let ev_ptr = stl_lookup(eid)
      
      if i > 0: kprintln("  |")
      
      kprint("  +-- ["); kprint_hex(eid); kprint("] ")
      
      if ev_ptr != nil:
        # Kind is at offset 0 (2 bytes)
        let kind_val = cast[ptr uint16](ev_ptr)[]
        if kind_val == uint16(EvSystemBoot): kprintln("SystemBoot")
        elif kind_val == uint16(EvFiberSpawn): kprintln("FiberSpawn")
        elif kind_val == uint16(EvCapabilityGrant): kprintln("CapGrant")
        elif kind_val == uint16(EvAccessDenied): kprintln("AccessDenied")
        else:
          kprint("Kind="); kprint_hex(uint64(kind_val)); kprintln("")
      else:
        kprintln("Unknown")

  kprintln("\n[STL] Summary complete.")

proc export_stl_binary*(dest: pointer, max_size: uint64): uint64 =
  ## Export STL events to a binary buffer
  return stl_export_binary(dest, max_size)
