//! The "protocol" library domain: the wire protocols — each service's public
//! interface, exposed as its own module (docs/driver-model.md). Both sides of
//! every conversation depend on the contract by name; neither reaches into the
//! other's files. Pure flat wire types: no protocol module imports anything.
//!
//! One module here is not a protocol but the shape the others are written in:
//!
//!   envelope                 : the packet prefix + comptime Define (docs/os-development/protocol-namespace.md)
//!
//!   vfs-protocol             : the VFS server <-> the file layer (unistd/stdio)
//!   input-protocol           : the input fan-out service <-> sources + subscribers
//!   block-protocol           : a filesystem <-> a block driver (usb-storage)
//!   usb-transfer-protocol    : a USB class driver <-> the xHCI bus driver
//!   device-manager-protocol  : the device manager <-> drivers + discovery
//!   display-protocol         : the compositor's client-facing surface
//!   scanout-protocol         : the compositor -> a native scanout driver (docs/display-v2.md)
//!   power-protocol           : system power's domain-named surface (docs/power.md)

const std = @import("std");

pub fn build(b: *std.Build) void {
    for ([_]struct { name: []const u8, root: []const u8 }{
        // Not a protocol, hence not `-protocol`: the envelope is what a
        // protocol is defined *through*.
        .{ .name = "envelope", .root = "envelope/envelope.zig" },
        .{ .name = "vfs-protocol", .root = "vfs/vfs-protocol.zig" },
        .{ .name = "input-protocol", .root = "input/input-protocol.zig" },
        .{ .name = "block-protocol", .root = "block/block-protocol.zig" },
        .{ .name = "usb-transfer-protocol", .root = "usb-transfer/usb-transfer-protocol.zig" },
        .{ .name = "device-manager-protocol", .root = "device-manager/device-manager-protocol.zig" },
        .{ .name = "display-protocol", .root = "display/display-protocol.zig" },
        .{ .name = "scanout-protocol", .root = "scanout/scanout-protocol.zig" },
        .{ .name = "power-protocol", .root = "power/power-protocol.zig" },
    }) |protocol| {
        _ = b.addModule(protocol.name, .{ .root_source_file = b.path(protocol.root) });
    }

    // Standalone `zig build test` for this domain alone; the root build keeps
    // its aggregate test step.
    const test_step = b.step("test", "Run the protocol unit tests");
    for ([_][]const u8{
        "envelope/envelope.zig", // framing round trips, verb numbering, dispatch, the floors
        "vfs/vfs-protocol.zig", // NodeKind / DirectoryEntry sizes + op values
        "display/display-protocol.zig", // pack(): native pixel encoding per format
    }) |root| {
        const protocol_tests = b.addTest(.{
            .root_module = b.createModule(.{
                .root_source_file = b.path(root),
                .target = b.resolveTargetQuery(.{}),
            }),
        });
        test_step.dependOn(&b.addRunArtifact(protocol_tests).step);
    }
}
