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

//! Per-sensor wire payloads: the inner protobufs the daemon ships in the
//! `payload` of each [`super::ReplyBody`] for streaming sensors.
//!
//! Every `*Sample` follows the same shape — a list of physical values
//! plus an `accuracy` rating in `0..=3` (0 unreliable, 3 high). Field
//! types and tags match the QMI traffic captured in `dump.txt`.

use prost::Message;

/// Inner request body for `MSG_REQ_ENABLE_REPORT_CONTINUOUS`.
#[derive(Clone, PartialEq, Message)]
pub struct RateConfig {
    /// Hz. Must match one of the values the daemon advertises in
    /// `ATTR_SAMPLE_RATE`, otherwise the SLPI silently clamps.
    #[prost(float, required, tag = "1")]
    pub sample_rate: f32,
}

/// Accelerometer: linear acceleration per axis in m/s².
/// `acceleration[0]` X, `[1]` Y, `[2]` Z.
#[derive(Clone, PartialEq, Message)]
pub struct AccelSample {
    #[prost(float, repeated, tag = "1")]
    pub acceleration: Vec<f32>,
    #[prost(int32, required, tag = "2")]
    pub accuracy: i32,
}

/// Gyroscope: angular rate per axis in rad/s.
#[derive(Clone, PartialEq, Message)]
pub struct GyroSample {
    #[prost(float, repeated, tag = "1")]
    pub velocity: Vec<f32>,
    #[prost(int32, required, tag = "2")]
    pub accuracy: i32,
}

/// Magnetometer: field strength per axis in µT.
#[derive(Clone, PartialEq, Message)]
pub struct MagSample {
    #[prost(float, repeated, tag = "1")]
    pub magnetic_field: Vec<f32>,
    #[prost(int32, required, tag = "2")]
    pub accuracy: i32,
}

/// Ambient light: `intensity[0]` is illuminance in lux,
/// `intensity[1]` (when present) is the chip's raw reading.
#[derive(Clone, PartialEq, Message)]
pub struct LightSample {
    #[prost(float, repeated, tag = "1")]
    pub intensity: Vec<f32>,
    #[prost(int32, required, tag = "2")]
    pub accuracy: i32,
}

/// Proximity: `near` is 1 when the user is in proximity (e.g. phone
/// against ear), 0 when far. `distance` is the chip's vendor-specific
/// raw output.
#[derive(Clone, PartialEq, Message)]
pub struct ProximitySample {
    #[prost(int32, required, tag = "1")]
    pub near: i32,
    #[prost(int32, required, tag = "2")]
    pub distance: i32,
    #[prost(int32, required, tag = "3")]
    pub accuracy: i32,
}

/// Rotation vector encoded as a quaternion:
/// X [0], Y [1], Z [2] are the imaginary components, W [3] the scalar.
#[derive(Clone, PartialEq, Message)]
pub struct RotvecSample {
    #[prost(float, repeated, tag = "1")]
    pub rotation: Vec<f32>,
    #[prost(int32, required, tag = "2")]
    pub accuracy: i32,
}
