//! Options trait contracts for the derive macro system.
//!
//! # Usage
//!
//! 1. Define a struct with `#[derive(Options)]`
//! 2. Implement [`OptionsContract`] for it
//! 3. Macro generates the partial struct and [`OptionsPartialContract`] impl

use crate::{OptionIssue, OptionsValidator};
use clap::FromArgMatches;
use serde::de::DeserializeOwned;

/// Contract for resolved options structs.
///
/// Implement this on the resolved type (e.g., `SharedOptions`).
pub trait OptionsContract: Sized {
    /// The partial type generated by the derive macro.
    type Partial: OptionsPartialContract;

    /// Validate the resolved options.
    ///
    /// Pushes any validation issues into the provided [`OptionsValidator`].
    fn validate(&self, validator: &mut OptionsValidator);
}

/// Contract for partial options structs.
///
/// Generated by the `#[derive(Options)]` macro on the partial type
/// (e.g., `SharedOptionsPartial`). This is what the macro produces.
pub trait OptionsPartialContract:
    Clone + Default + DeserializeOwned + FromArgMatches + Sized
{
    /// The resolved options type.
    type Resolved: OptionsContract;

    /// Merge another partial into self (other fills in None/NotSet values).
    fn merge(&mut self, other: Self);

    /// Resolve partial into final options, applying defaults.
    ///
    /// Does not check required fields or run validation.
    /// Use `resolve()` for full validation.
    fn resolve_without_validation(self) -> Self::Resolved;

    /// Resolve partial into final options with validation.
    ///
    /// Checks required fields are present and runs validation.
    /// Returns `Err` with all validation issues if any checks fail.
    fn resolve(self) -> Result<Self::Resolved, Vec<OptionIssue>>;
}
