# Module System

The module system enables dynamic loading of policy modules. Implemented in Phase 4.

## Overview

| Component | Location | Purpose |
|-----------|----------|---------|
| `Module` trait | `server/lib/kernel/src/api/module/mod.rs` | Module interface |
| `declare_module!` | `shared/module-macros/` | FFI entry points |
| `ModuleRegistry` | `server/lib/server/src/registry/mod.rs` | Dependency resolution |
| `PythonModule` | `server/lib/drivers/ffi-python/` | Python module wrapper |

## Module Types

Reovim supports multiple module types:

| Type | Extension | Build | Feature Flag |
|------|-----------|-------|--------------|
| Rust (static) | - | Compile-time | - |
| Rust (dynamic) | `.so`/`.dylib`/`.dll` | Runtime | - |
| C/FFI | `.so`/`.dylib`/`.dll` | Runtime | - |
| Python | `.py` | Runtime | `python` |

All module types implement the same `Module` trait and participate in the
same lifecycle, dependency resolution, and hot reload system.

---

## Module Trait

```rust
// server/lib/kernel/src/api/module/mod.rs

pub trait Module: Send + Sync + 'static {
    // Identity
    fn id(&self) -> ModuleId;
    fn name(&self) -> &'static str;
    fn version(&self) -> Version;
    fn api_version(&self) -> Version { API_VERSION }

    // Dependencies
    fn dependencies(&self) -> Vec<ModuleId> { vec![] }
    fn optional_dependencies(&self) -> Vec<ModuleId> { vec![] }

    // Lifecycle
    fn init(&mut self, ctx: &ModuleContext) -> ProbeResult;
    fn exit(&mut self) -> Result<(), ModuleError>;

    // Lifecycle Hooks
    fn on_all_loaded(&mut self, _ctx: &ModuleContext) {}
    fn on_buffer_focus(&mut self, _buffer_id: BufferId, _ctx: &ModuleContext) {}
    fn on_unload(&mut self) -> Result<(), ModuleError> { Ok(()) }

    // Declarative registrations
    fn commands(&self) -> Vec<CommandRegistration> { vec![] }
    fn keybindings(&self) -> Vec<KeybindingRegistration> { vec![] }
    fn event_handlers(&self) -> Vec<EventHandlerRegistration> { vec![] }

    // Hot Reload Support
    fn supports_hot_reload(&self) -> bool { false }
    fn save_state(&self) -> Option<Box<[u8]>> { None }
    fn restore_state(&mut self, _data: &[u8]) -> Result<(), ModuleError> { Ok(()) }
}
```

### Lifecycle

```
┌─────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
│ Created │ ──▶ │  Init   │ ──▶ │ Running │ ──▶ │  Exit   │
└─────────┘     └─────────┘     └─────────┘     └─────────┘
     │               │               │               │
     │             init(ctx)      (active)         exit()
     │               │               │               │
     ▼               ▼               ▼               ▼
  new()         ProbeResult      handle events   cleanup
```

### ProbeResult

```rust
pub enum ProbeResult {
    Success,              // Module ready
    Defer(String),        // Try again later, with reason (Linux: -EPROBE_DEFER)
    Failed(ModuleError),  // Permanent failure
}
```

---

## declare_module! Macro

Generates FFI-safe entry points for dynamic loading.

```rust
// In your module crate
use reovim_kernel::api::v1::*;
use reovim_module_macros::declare_module;

pub struct MyModule { /* ... */ }

impl Module for MyModule {
    fn id(&self) -> ModuleId { ModuleId::new("my-module") }
    fn name(&self) -> &'static str { "My Module" }
    fn version(&self) -> Version { Version::new(1, 0, 0) }

    fn init(&mut self, ctx: &ModuleContext) -> ProbeResult {
        // Initialize module
        ProbeResult::Success
    }

    fn exit(&mut self) -> Result<(), ModuleError> {
        // Cleanup
        Ok(())
    }
}

declare_module!(MyModule);
```

### Generated FFI Functions

```rust
// Generated by declare_module!

#[no_mangle]
pub static REOVIM_MODULE_API_VERSION: Version = API_VERSION;

#[no_mangle]
pub extern "C" fn reovim_module_probe() -> ModuleProbe { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_entry() -> *mut c_void { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_init(ptr: *mut c_void, ctx: *const ModuleContext) -> i32 { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_exit(ptr: *mut c_void) -> i32 { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_destroy(ptr: *mut c_void) { /* ... */ }

// Hot reload support
#[no_mangle]
pub extern "C" fn reovim_module_supports_hot_reload() -> bool { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_save_state(ptr: *mut c_void, ...) -> i32 { /* ... */ }

#[no_mangle]
pub extern "C" fn reovim_module_restore_state(ptr: *mut c_void, ...) -> i32 { /* ... */ }
```

---

## ModuleProbe

FFI-safe metadata without instantiation.

```rust
#[repr(C)]
pub struct ModuleProbe {
    pub id: [u8; 64],           // Module ID (null-terminated)
    pub name: [u8; 128],        // Display name
    pub version: Version,       // Module version
    pub api_version: Version,   // Required API version

    // Dependencies (up to 8 each)
    pub required_deps: [[u8; 64]; 8],
    pub optional_deps: [[u8; 64]; 8],
    pub required_count: u8,
    pub optional_count: u8,

    pub rustc_version: [u8; 32], // Compiler version for ABI check
}
```

---

## ModuleRegistry

Manages module lifecycle with dependency resolution.

```rust
// server/lib/server/src/registry/mod.rs

pub struct ModuleRegistry {
    modules: HashMap<ModuleId, ModuleHandle>,
    dependency_graph: DependencyGraph,
}

impl ModuleRegistry {
    // Initialize all modules in dependency order
    pub fn init_all(&mut self, ctx: &KernelContext) -> Result<()>;

    // Shutdown in reverse order
    pub fn shutdown(&mut self) -> Result<()>;

    // Single module operations
    pub fn load(&mut self, handle: ModuleHandle) -> Result<()>;
    pub fn unload(&mut self, id: &ModuleId) -> Result<()>;
    pub fn reload(&mut self, id: &ModuleId, ctx: &KernelContext) -> Result<()>;
}
```

### Dependency Resolution

Uses Kahn's algorithm for topological sort:

```
A depends on B, C
B depends on D
C depends on D

Load order: D → B → C → A
Unload order: A → C → B → D
```

### Deferred Probing

Linux-style retry for circular or late dependencies:

```
Pass 1: Load all modules, some return Defer
Pass 2: Retry deferred modules
Pass 3: Final retry, fail if still deferred
```

---

## Registration Types

Declarative metadata for commands, keybindings, events.

### CommandRegistration

```rust
pub struct CommandRegistration {
    pub id: &'static str,
    pub name: &'static str,
    pub description: &'static str,
    pub category: Option<&'static str>,
    capabilities: u8,                       // Bitfield: accepts_count, accepts_motion, is_jump, is_text_modifying
    pub depends_on: &'static [&'static str],
    pub flags: RegistrationFlags,
}

// Usage
fn commands(&self) -> Vec<CommandRegistration> {
    vec![
        CommandRegistration::new("delete")
            .with_name("Delete")
            .with_description("Delete text")
            .with_category("operator")
            .with_count()
            .with_motion()
            .with_text_modifying()
            .with_depends_on(&["yank"])
            .with_flags(RegistrationFlags::required()),
    ]
}
```

### KeybindingRegistration

```rust
pub struct KeybindingRegistration {
    pub keys: &'static str,
    pub command_id: CommandId,
    pub modes: &'static [&'static str],
    pub description: &'static str,
    pub category: Option<&'static str>,
    pub enabled: bool,
    pub priority: u32,
    pub depends_on: &'static [&'static str],
    pub flags: RegistrationFlags,
}

// Usage
fn keybindings(&self) -> Vec<KeybindingRegistration> {
    vec![
        KeybindingRegistration::new("dd", DELETE_LINE)
            .with_modes(&["normal"])
            .with_description("Delete current line")
            .with_category("operator")
            .with_priority(50),
    ]
}
```

### EventHandlerRegistration

```rust
pub struct EventHandlerRegistration {
    pub event_type: &'static str,
    pub priority: u32,
    pub description: &'static str,
    pub once: bool,
    pub target_component: Option<&'static str>,
    pub depends_on: &'static [&'static str],
    pub flags: RegistrationFlags,
}

// Usage
fn event_handlers(&self) -> Vec<EventHandlerRegistration> {
    vec![
        EventHandlerRegistration::new("BufferChanged")
            .with_priority(50)
            .with_description("Update cursor highlight")
            .with_target("treesitter")
            .with_depends_on(&["syntax-highlight"]),
    ]
}
```

---

## Example Module

Complete example of a policy module:

```rust
use reovim_kernel::api::v1::*;
use reovim_module_macros::declare_module;

// Define command IDs (compile-time verified)
const KEYMAP: ModuleId = ModuleId::new("keymap");
const CURSOR_DOWN: CommandId = CommandId::new(KEYMAP, "cursor-down");
const CURSOR_UP: CommandId = CommandId::new(KEYMAP, "cursor-up");
const CURSOR_LEFT: CommandId = CommandId::new(KEYMAP, "cursor-left");
const CURSOR_RIGHT: CommandId = CommandId::new(KEYMAP, "cursor-right");

pub struct KeymapModule;

impl KeymapModule {
    pub fn new() -> Self {
        Self
    }
}

impl Module for KeymapModule {
    fn id(&self) -> ModuleId { ModuleId::new("keymap") }
    fn name(&self) -> &'static str { "Keymap" }
    fn version(&self) -> Version { Version::new(1, 0, 0) }

    fn init(&mut self, _ctx: &ModuleContext) -> ProbeResult {
        ProbeResult::Success
    }

    fn exit(&mut self) -> Result<(), ModuleError> {
        Ok(())
    }

    fn keybindings(&self) -> Vec<KeybindingRegistration> {
        vec![
            KeybindingRegistration::new("j", CURSOR_DOWN).with_modes(&["normal"]),
            KeybindingRegistration::new("k", CURSOR_UP).with_modes(&["normal"]),
            KeybindingRegistration::new("h", CURSOR_LEFT).with_modes(&["normal"]),
            KeybindingRegistration::new("l", CURSOR_RIGHT).with_modes(&["normal"]),
        ]
    }
}

declare_module!(KeymapModule);
```

---

## Related Documents

- [Architecture Overview](../architecture/overview.md) - Architecture overview
- [Mechanism vs Policy](../contributing/philosophy/mechanism-vs-policy.md) - Design principle
- [Module-Mode Inheritance](./mode-inheritance.md) - Mode system
- [Kernel Subsystems](../kernel/overview.md) - Kernel internals
- [FFI Overview](../ffi/overview.md) - C FFI interface
- [Python FFI](../ffi/python.md) - Python module bindings
- [Python Modules User Guide](../../user-guide/python-modules.md) - Writing Python modules
