"""
BloomOS Kernel-Mode ABI
=======================

Transforms BloomOS from orchestrator code into a substrate OS with:
1. SyscallRegistry - Canonical syscall ABI with versioned schemas and receipts
2. ITTokenLedger - Unified resource accounting (cpu_ms, io_bytes, ram_bytes)
3. CellWall - Minimal security boundary with allowlists

Usage:
    from helix_cdc.bloomos.kernel import get_kernel

    kernel = get_kernel()
    result, receipt = kernel.registry.invoke("cdna.decode.v1", "actor", inputs)

Enable kernel mode:
    export BLOOMOS_MODE=kernel
"""

from __future__ import annotations

import os
from typing import TYPE_CHECKING

from .syscall_receipt import SyscallReceipt, create_receipt
from .it_token_ledger import ITTokenLedger, LedgerEntry
from .cell_wall import CellWall, ActorPolicy, Capability
from .syscall_registry import SyscallRegistry, REGISTRY_VERSION, ROUTER_VERSION_HASH

if TYPE_CHECKING:
    from typing import Optional


__all__ = [
    # Core classes
    "SyscallReceipt",
    "ITTokenLedger",
    "LedgerEntry",
    "CellWall",
    "ActorPolicy",
    "Capability",
    "SyscallRegistry",
    # Factory function
    "get_kernel",
    "BloomOSKernel",
    # Constants
    "REGISTRY_VERSION",
    "ROUTER_VERSION_HASH",
]


class BloomOSKernel:
    """
    BloomOS Kernel singleton.

    Provides unified access to:
    - registry: SyscallRegistry for invoking syscalls
    - ledger: ITTokenLedger for resource accounting
    - cell_wall: CellWall for authorization

    Usage:
        kernel = get_kernel()
        result, receipt = kernel.registry.invoke("cdna.decode.v1", "bridge", inputs)
    """

    def __init__(self):
        """Initialize kernel components."""
        self.ledger = ITTokenLedger()
        self.cell_wall = CellWall()
        self.registry = SyscallRegistry(self.ledger, self.cell_wall)

        # Register initial syscalls
        self._register_default_syscalls()

    def _register_default_syscalls(self) -> None:
        """Register default syscalls from handlers."""
        from .handlers import register_all_handlers
        register_all_handlers(self.registry)

    def stats(self) -> dict:
        """Get kernel statistics."""
        return {
            "version": REGISTRY_VERSION,
            "router_version_hash": ROUTER_VERSION_HASH,
            "registry": self.registry.stats(),
            "ledger": self.ledger.stats(),
            "cell_wall": self.cell_wall.stats(),
        }


# Singleton instance
_kernel_instance: Optional[BloomOSKernel] = None


def get_kernel() -> BloomOSKernel:
    """
    Get the BloomOS kernel singleton.

    Creates the kernel on first call, returns existing instance on subsequent calls.

    Returns:
        BloomOSKernel instance
    """
    global _kernel_instance
    if _kernel_instance is None:
        _kernel_instance = BloomOSKernel()
    return _kernel_instance


def is_kernel_mode() -> bool:
    """Check if BloomOS is running in kernel mode."""
    return os.getenv("BLOOMOS_MODE", "direct") == "kernel"


def reset_kernel() -> None:
    """Reset the kernel singleton (for testing)."""
    global _kernel_instance
    _kernel_instance = None
