// vi:syntax=yggdrasil-abi:

// abi::io

newtype RawFd(u31);

newtype UserId(u32);
newtype GroupId(u32);

newtype ChannelPublisherId(u32);

bitfield FileMode(u32) {
    /// Other user execution access
    OTHER_EXEC: 0,
    /// Other user write access
    OTHER_WRITE: 1,
    /// Other user read access
    OTHER_READ: 2,

    /// Group execution access
    GROUP_EXEC: 3,
    /// Group write access
    GROUP_WRITE: 4,
    /// Group read access
    GROUP_READ: 5,

    /// User execution access
    USER_EXEC: 6,
    /// User write access
    USER_WRITE: 7,
    /// User read access
    USER_READ: 8,
}

bitfield RemoveFlags(u32) {
    DIRECTORY: 1,
    DIRECTORY_ONLY: 2,
}

bitfield FileSync(u32) {
    DATA: 0,
    METADATA: 1,
}

bitfield AccessMode(u32) {
    READ: 0,
    WRITE: 1,
    EXEC: 2,
}

bitfield OpenOptions(u32) {
    /// The file is to be opened with read capability
    READ: 0,
    /// The file is to be opened with write capability
    WRITE: 1,

    /// Open file at the end
    APPEND: 2,
    /// Truncate the file to zero bytes when opening
    TRUNCATE: 3,

    /// Create the file if it does not exist
    CREATE: 4,
    /// When combined with CREATE, will fail if the file already exists
    CREATE_EXCL: 5,
}

enum FileType(u32) {
    /// Regular file
    File = 1,
    /// Directory
    Directory = 2,
    /// Not yet implemented
    Symlink = 3,
    /// Block device
    Block = 4,
    /// Character device (e.g. terminal)
    Char = 5,
}

/// Describes metadata associated with a filesystem entry
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
struct FileAttr {
    /// Data size for files, UNSPECIFIED for the rest
    pub size: u64,
    /// Filesystem-specific block size
    pub block_size: u64,
    /// Number of filesystem blocks (not including metadata) occupied by the entry
    pub block_count: u64,

    /// Filesystem-specific node number
    pub inode: Option<u32>,

    /// Entry type
    pub ty: FileType,
    /// Entry access permissions
    pub mode: FileMode,

    /// Owner user ID
    pub uid: UserId,
    /// Owner group ID
    pub gid: GroupId,

    /// Creation time
    pub ctime: SystemTime,
    /// Last modification time
    pub mtime: SystemTime,
    /// Last access time
    pub atime: SystemTime,
}

/// Raw directory entry representation
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
struct DirectoryEntry {
    /// Name of the entry
    pub name: FixedString<256>,
    /// Type of the entry
    pub ty: Option<FileType>,
}

enum PollControl(u32) {
    AddFd = 1,
    RemoveFd = 2,
}

bitfield TimerOptions(u32) {
    REPEAT: 0,
}

// abi::io::terminal

#[derive(Clone, Copy, Debug)]
#[repr(C)]
struct TerminalControlCharacters {
    /// End-of-file character (0x04, ^D)
    pub eof: u8,
    /// Erase character (0x7F, ^?)
    pub erase: u8,
    /// Word erase character (0x17, ^W)
    pub werase: u8,
    /// Interrupt character (0x03, ^C)
    pub interrupt: u8,
    /// Kill character (0x15, ^U)
    pub kill: u8,
}

/// Controls the line discipline of the terminal
#[default(SIGNAL | CANONICAL | ECHO | ECHO_ERASE | ECHO_KILL | ECHO_NL)]
bitfield TerminalLineOptions(u32) {
    /// Enables signal processing for special bytes (INTR, QUIT, etc.)
    SIGNAL: 0,
    /// Enables canonical mode
    CANONICAL: 1,
    /// Echo input characters back
    ECHO: 2,
    /// If CANONICAL is set, ERASE character erases chars, WORD_ERASE erases words
    ECHO_ERASE: 3,
    /// If CANONICAL is set, KILL erases lines
    ECHO_KILL: 4,
    /// If CANONICAL is set, echo newline even if ECHO is not set
    ECHO_NL: 5,
}

/// Defines how output to the terminal should be processed
#[default(NL_TO_CRNL)]
bitfield TerminalOutputOptions(u32) {
    /// Translate \n to \r\n
    NL_TO_CRNL: 0,
}

/// Defines how input should be presented to the reader
#[default(CR_TO_NL)]
bitfield TerminalInputOptions(u32) {
    /// Translate \n to \r on input
    NL_TO_CR: 0,
    /// Translate \r to \n on input
    CR_TO_NL: 1,
}

/// Terminal I/O transformation and control settings
#[derive(Clone, Copy, Debug)]
#[repr(C)]
struct TerminalOptions {
    /// Controls output processing
    pub output: TerminalOutputOptions,
    /// Controls input processing
    pub input: TerminalInputOptions,
    /// Controls special bytes and line discipline
    pub line: TerminalLineOptions,
    /// Specifies control characters of the terminal
    pub chars: TerminalControlCharacters,
    /// For hardware terminals, controls baud rate used for the communication line
    pub baud_rate: u32
}

/// Describes terminal size in rows and columns
#[derive(Clone, Copy, Debug)]
#[repr(C)]
struct TerminalSize {
    /// Number of text rows
    pub rows: usize,
    /// Number of text columns
    pub columns: usize,
}

// abi::io::device

/// Describes how a mount operation should be performed
#[derive(Clone, Debug)]
#[repr(C)]
struct MountOptions<'a> {
    /// Block device to use as a mount source. May be empty when mounting virtual filesystems.
    pub source: Option<&'a str>,
    /// Filesystem to use when mounting. Empty means "deduce automatically" and source must be set.
    pub filesystem: Option<&'a str>,
    /// Extra filesystem options.
    pub options: Option<&'a str>,
    /// Path to a directory to mount the filesystem to
    pub target: &'a str,
}

/// Describes how an unmount operation should be performed
#[derive(Clone, Debug)]
#[repr(C)]
struct UnmountOptions {
    /// Path to the mountpoint to unmount
    pub mountpoint: &'static str,
}

