//! Example: Subject Binding for Re-Authentication (FR-027)
//!
//! Demonstrates using subject DID matching for re-authentication scenarios
//! where you need to verify the same user who previously authenticated.
//!
//! # Use Case
//!
//! A banking application needs to:
//! 1. Store the user's DID after initial authentication
//! 2. On subsequent logins, require the SAME DID to present credentials
//! 3. Prevent credential sharing between users
//!
//! # Running
//!
//! ```bash
//! cargo run --example subject_binding --features persona-policy
//! ```

use lastid_sdk::{BaseCredentialPolicy, PersonaField, PersonaPolicy, PolicyBuilder};

fn main() {
    println!("=== Subject Binding for Re-Authentication ===\n");

    // Simulate: stored DID from initial authentication
    let stored_user_did = "did:lastid:user-abc123";
    println!("Stored user DID from initial auth: {stored_user_did}\n");

    // Example 1: Re-authenticate with BaseCredentialPolicy
    println!("1. Re-Authentication with Base Credential");
    let policy = BaseCredentialPolicy::new()
        .with_subject_did(stored_user_did)
        .with_state("csrf-token-xyz") // CSRF protection
        .with_nonce("fresh-nonce-123") // Replay protection
        .with_callback("https://example.com/callback");

    let request = policy.clone().to_request().unwrap();
    let constraints = request.constraints.unwrap();
    println!("   Subject DID: {}", constraints.get("sub").unwrap());
    println!("   State: {:?}", request.state);
    println!("   Nonce: {:?}", request.nonce);
    println!();

    // Example 2: Re-authenticate with Persona for profile data
    println!("2. Re-Authentication with Persona Credential");
    let policy = PersonaPolicy::new()
        .with_subject_did(stored_user_did)
        .with_fields(&[PersonaField::DisplayName])
        .with_optional_fields(&[PersonaField::Email, PersonaField::Phone])
        .with_callback("https://example.com/callback");

    let request = policy.clone().to_request().unwrap();
    let constraints = request.constraints.unwrap();
    println!("   Subject DID: {}", constraints.get("sub").unwrap());
    println!("   Required fields: {:?}", request.required_fields);
    println!();

    // Example 3: Combined subject + issuer binding
    println!("3. Strict Re-Authentication (Subject + Issuer)");
    let policy = BaseCredentialPolicy::new()
        .with_subject_did(stored_user_did)
        .with_issuer_did("did:lastid:trusted-issuer")
        .with_callback("https://example.com/callback");

    let request = policy.clone().to_request().unwrap();
    let constraints = request.constraints.unwrap();
    println!("   Subject DID: {}", constraints.get("sub").unwrap());
    println!("   Issuer DID: {}", constraints.get("iss").unwrap());
    println!("   (Only accepts credentials from trusted issuer for this user)");
    println!();

    // Example 4: Custom claim constraint
    println!("4. Re-Authentication with Custom Claim");
    let policy = BaseCredentialPolicy::new()
        .with_subject_did(stored_user_did)
        .with_claim_constraint("account_tier", serde_json::json!("premium"))
        .with_callback("https://example.com/callback");

    let request = policy.to_request().unwrap();
    let constraints = request.constraints.unwrap();
    println!("   Subject DID: {}", constraints.get("sub").unwrap());
    println!(
        "   Account Tier: {}",
        constraints.get("account_tier").unwrap()
    );

    println!("\n=== Subject Binding Example Complete ===");
}
