//! Configuration types for s3bolt.

use std::path::PathBuf;

use chrono::{DateTime, Utc};

use crate::types::S3Uri;

/// Top-level configuration for a copy operation.
#[derive(Debug, Clone)]
pub struct CopyConfig {
    pub source: S3Uri,
    pub destination: S3Uri,
    pub recursive: bool,
    pub sync_mode: bool,
    pub dry_run: bool,
    pub verify: bool,
    pub filters: FilterConfig,
    pub concurrency: ConcurrencyConfig,
    pub checkpoint_path: Option<PathBuf>,
    pub resume: bool,
    pub storage_class: Option<String>,
    pub sse: Option<SseConfig>,
    pub preserve_metadata: bool,
    pub source_profile: Option<String>,
    pub dest_profile: Option<String>,
}

/// Filters to select which objects to copy.
#[derive(Debug, Clone, Default)]
pub struct FilterConfig {
    /// Glob patterns — at least one must match (OR within group).
    pub include_globs: Vec<String>,
    /// Glob patterns — if any match, the object is excluded.
    pub exclude_globs: Vec<String>,
    /// Regex applied to the full key path.
    pub key_regex: Option<String>,
    /// Minimum object size in bytes.
    pub min_size: Option<u64>,
    /// Maximum object size in bytes.
    pub max_size: Option<u64>,
    /// Only objects modified after this timestamp.
    pub newer_than: Option<DateTime<Utc>>,
    /// Only objects modified before this timestamp.
    pub older_than: Option<DateTime<Utc>>,
}

/// Controls concurrency behavior.
#[derive(Debug, Clone)]
pub struct ConcurrencyConfig {
    /// Maximum concurrent copy operations.
    pub max_concurrent: u32,
    /// Enable adaptive concurrency (AIMD).
    pub adaptive: bool,
    /// Minimum concurrent operations (floor for AIMD).
    pub min_concurrent: u32,
    /// Buffer size for the listing-to-copy channel.
    pub listing_buffer_size: usize,
}

impl Default for ConcurrencyConfig {
    fn default() -> Self {
        Self {
            max_concurrent: 256,
            adaptive: true,
            min_concurrent: 8,
            listing_buffer_size: 10_000,
        }
    }
}

/// Server-side encryption configuration.
#[derive(Debug, Clone)]
pub struct SseConfig {
    /// Encryption algorithm: `"aws:kms"` or `"AES256"`.
    pub algorithm: String,
    /// KMS key ARN (required when algorithm is `"aws:kms"`).
    pub kms_key_id: Option<String>,
}
