//! BackupGroup — multi-component consistency points.

use serde::{Deserialize, Serialize};

use super::component::{Destination, RetentionPolicy, ScheduleSpec, TagStrategy, VaultKeyRef,
                        VerifyPolicyRef};

/// Member of a [`BackupGroup`].
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupMember {
    /// Component name.
    pub component: String,
    /// Optional scope filter; omitted means all scopes of the component.
    #[serde(default)]
    pub scope: Option<String>,
}

/// Coordination strategy discriminator.
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CoordinationKind {
    /// Snapshots fired in parallel; consistency is tag-based (group_id).
    BestEffort,
    /// Ordered pre-hooks pause writers, snapshot, unquiesce. Bounded downtime.
    QuiesceWindow,
    /// Atomic at CSI layer via Longhorn VolumeSnapshotGroup.
    CsiConsistentGroup,
}

/// Coordination strategy applied during a group run.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoordinationStrategy {
    /// Variant.
    pub kind: CoordinationKind,
    /// Quiesce sequence (`QuiesceWindow`).
    #[serde(default)]
    pub quiesce_seq: Vec<String>,
    /// Maximum downtime for `QuiesceWindow`.
    #[serde(default)]
    pub max_downtime: Option<String>,
    /// CSI VolumeSnapshotClass for `CsiConsistentGroup`.
    #[serde(default)]
    pub snapshot_class: Option<String>,
}

/// A group of components/scopes captured atomically (à la Chandy-Lamport).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackupGroup {
    /// Group identifier (used in CLI: `--group <name>`).
    pub name: String,
    /// Members participating in the consistent cut.
    pub members: Vec<GroupMember>,
    /// Group schedule (independent of per-member policies).
    pub schedule: ScheduleSpec,
    /// Coordination strategy.
    pub coordination: CoordinationStrategy,
    /// Retention shared across all members for the group's snapshots.
    pub retention: RetentionPolicy,
    /// Destinations (same `MultiDestinationRequired` invariant).
    pub destinations: Vec<Destination>,
    /// Encryption key.
    pub encryption: VaultKeyRef,
    /// Tag strategy.
    pub tag_strategy: TagStrategy,
    /// Optional verify reference.
    #[serde(default)]
    pub verify: Option<VerifyPolicyRef>,
}
