//! Voice transmit mode (SDD-095).
//!
//! Selects how `transmit_active` is driven from the user's input
//! signals. Persisted per-identity in
//! [`chanora_storage::IdentityFileStore`] under the `transmit_mode`
//! metadata key (default [`TransmitMode::Ptt`]).
//!
//! `VoiceActivity` is driven by Rust-owned VAD state in P1.

/// User-visible voice transmit mode.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum TransmitMode {
    /// Push-to-talk: transmit only while the bound key is held
    /// (with release-tail per SDD-096).
    #[default]
    Ptt = 0,
    /// Continuous: transmit whenever the user is in a voice
    /// channel and not hard-muted.
    Continuous = 1,
    /// Voice activity detection.
    VoiceActivity = 2,
}

impl TransmitMode {
    /// Encode as the persisted single-byte value.
    pub fn as_u8(self) -> u8 {
        self as u8
    }

    /// Decode from the persisted single-byte value. Returns
    /// `None` for unknown encodings (the storage layer should
    /// fall back to [`TransmitMode::default`] in that case).
    pub fn from_u8(v: u8) -> Option<Self> {
        match v {
            0 => Some(Self::Ptt),
            1 => Some(Self::Continuous),
            2 => Some(Self::VoiceActivity),
            _ => None,
        }
    }

    /// Stable diagnostic identifier (never localised).
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Ptt => "ptt",
            Self::Continuous => "continuous",
            Self::VoiceActivity => "voice-activity",
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn default_is_ptt() {
        assert_eq!(TransmitMode::default(), TransmitMode::Ptt);
    }

    #[test]
    fn round_trip_u8() {
        for m in [
            TransmitMode::Ptt,
            TransmitMode::Continuous,
            TransmitMode::VoiceActivity,
        ] {
            assert_eq!(TransmitMode::from_u8(m.as_u8()), Some(m));
        }
        assert_eq!(TransmitMode::from_u8(99), None);
    }

    #[test]
    fn as_str_is_stable() {
        assert_eq!(TransmitMode::Ptt.as_str(), "ptt");
        assert_eq!(TransmitMode::Continuous.as_str(), "continuous");
        assert_eq!(TransmitMode::VoiceActivity.as_str(), "voice-activity");
    }
}
