// SPDX-License-Identifier: MPL-2.0
// Copyright (C) 2026 Petr Hodina <petr.hodina@protonmail.com>

//! Attribute query: ask the daemon for a sensor's metadata (name, vendor,
//! advertised rates and ranges, FIFO size, mount matrix, ...).

use prost::Message;

/// Inner request body for `MSG_REQ_GET_ATTRIBUTES`.
#[derive(Clone, PartialEq, Message)]
pub struct AttrQuery {
    /// `true` keeps a subscription open for attribute changes.
    /// Field number is intentionally `2` — the daemon expects that tag.
    #[prost(bool, optional, tag = "2")]
    pub subscribe: Option<bool>,
}

/// One value cell in an attribute response. Exactly one of the optional
/// fields is populated, depending on the attribute's declared type.
#[derive(Clone, PartialEq, Message)]
pub struct AttrCell {
    /// Recursive nested array — used by attributes like `MOUNT_MATRIX`
    /// whose value is itself a list of values. Boxed so the type has a
    /// finite compile-time size.
    #[prost(message, optional, boxed, tag = "1")]
    pub array: Option<Box<AttrValues>>,
    #[prost(string, optional, tag = "2")]
    pub string_value: Option<String>,
    #[prost(float, optional, tag = "3")]
    pub float_value: Option<f32>,
    /// Encoded on the wire as `fixed64` even when the logical attribute
    /// is a 32-bit count.
    #[prost(fixed64, optional, tag = "4")]
    pub int_value: Option<u64>,
    #[prost(bool, optional, tag = "5")]
    pub bool_value: Option<bool>,
}

/// Wrapper around a list of [`AttrCell`]s. Used in two positions in the
/// wire format: top-level under [`Attr::values`] and recursively inside
/// [`AttrCell::array`]. Both encode identically (one tag-1 repeated
/// message), so a single Rust type covers both.
#[derive(Clone, PartialEq, Message)]
pub struct AttrValues {
    #[prost(message, repeated, tag = "1")]
    pub items: Vec<AttrCell>,
}

/// One attribute entry in an [`AttrResponse`]: an integer ID plus the
/// list of values associated with it.
#[derive(Clone, PartialEq, Message)]
pub struct Attr {
    #[prost(int32, required, tag = "1")]
    pub id: i32,
    #[prost(message, required, tag = "2")]
    pub values: AttrValues,
}

/// Response for `MSG_RESP_GET_ATTRIBUTES`. One [`Attr`] per attribute the
/// daemon advertises for the sensor.
#[derive(Clone, PartialEq, Message)]
pub struct AttrResponse {
    #[prost(message, repeated, tag = "1")]
    pub entries: Vec<Attr>,
}
