//! The power protocol (docs/power.md): system power's domain-named surface,
//! registered under `ServiceId.power`. On x86 the acpi service serves it; on
//! ARM a PSCI/mailbox service will register the same id — subscribers never
//! learn which firmware they are on (docs/discovery.md — firmware neutrality).
//! The vfs-protocol pattern: extern-struct messages, a version, reserved fields.

/// The protocol version a client states nowhere yet — reserved for the day a
/// handshake needs it; requests carry it so a mismatch can be refused loudly.
pub const version: u16 = 1;

pub const Operation = enum(u8) {
    /// Subscribe to power events: the subscriber's endpoint rides as the
    /// call's capability (the input/device-manager pattern); events arrive on
    /// it as buffered messages carrying an `EventMessage`.
    subscribe = 1,
    /// Orderly shutdown's last step: enter S5. Accepted only from PID 1
    /// (init) — the process that has already run the stop sequence over
    /// everything else.
    shutdown = 2,
    /// The published event payload (never sent *to* the service).
    event = 3,
};

/// What happened. The vocabulary is hardware-neutral: a lid is a lid whether
/// ACPI or a PSCI mailbox reported it.
pub const Event = enum(u8) {
    power_button = 1,
    lid = 2,
    ac = 3,
    battery = 4,
    /// A device notification that maps to none of the named events — the
    /// `code` and `hid` fields say which device and what code.
    notify = 5,
};

pub const Subscribe = extern struct {
    operation: u8 = @intFromEnum(Operation.subscribe),
    reserved0: u8 = 0,
    version: u16 = version,
    reserved1: u32 = 0,
};

pub const Shutdown = extern struct {
    operation: u8 = @intFromEnum(Operation.shutdown),
    reserved0: u8 = 0,
    version: u16 = version,
    reserved1: u32 = 0,
};

/// A published event, as the buffered-message payload subscribers receive.
pub const EventMessage = extern struct {
    operation: u8 = @intFromEnum(Operation.event),
    /// An Event value.
    event: u8,
    reserved0: u16 = 0,
    /// The device notification code (Notify's second argument), or 0.
    code: u32 = 0,
    /// The notifying device's hardware id (EISA-decoded), or all zero.
    hid: [8]u8 = .{0} ** 8,
};

pub const Reply = extern struct {
    status: i32,
    reserved: u32 = 0,
};

/// Upper bound on any message in this protocol — sizes endpoint buffers.
pub const message_maximum = 64;
