//! Agent-to-agent (A2A) delegation methods for `AgentIdPClient`.
//!
//! Covers `POST /delegation` and `POST /delegation/verify`.

use crate::agents::parse_response;
use crate::client::AgentIdPClient;
use crate::error::AgentIdPError;
use crate::models::{DelegateRequest, DelegationToken, DelegationVerification};

impl AgentIdPClient {
    /// Creates an A2A delegation token granting a delegatee agent authority
    /// to act on behalf of the calling (delegator) agent.
    ///
    /// `POST /delegation` → `201 DelegationToken`
    ///
    /// # Errors
    ///
    /// Returns [`AgentIdPError::DelegationError`] when the delegation chain
    /// would be invalid (e.g. cyclic delegation or insufficient scope).
    pub async fn delegate(
        &self,
        req: DelegateRequest,
    ) -> Result<DelegationToken, AgentIdPError> {
        let auth = self.get_auth_header().await?;
        let url = format!("{}/delegation", self.base_url);

        let resp = self
            .http
            .post(&url)
            .header("Authorization", auth)
            .json(&req)
            .send()
            .await?;

        // Map 422 Unprocessable Entity to DelegationError.
        if resp.status().as_u16() == 422 {
            let body: serde_json::Value =
                resp.json().await.unwrap_or(serde_json::Value::Null);
            let msg = body
                .get("message")
                .and_then(|v| v.as_str())
                .unwrap_or("invalid delegation chain")
                .to_owned();
            return Err(AgentIdPError::DelegationError(msg));
        }

        parse_response(resp).await
    }

    /// Verifies an A2A delegation token and returns its claims.
    ///
    /// `POST /delegation/verify` → `200 DelegationVerification`
    ///
    /// The response's `valid` field is `false` when the token is expired or
    /// the chain has been revoked, rather than returning an error.
    pub async fn verify_delegation(
        &self,
        token: &str,
    ) -> Result<DelegationVerification, AgentIdPError> {
        let auth = self.get_auth_header().await?;
        let url = format!("{}/delegation/verify", self.base_url);

        let body = serde_json::json!({ "delegation_token": token });

        let resp = self
            .http
            .post(&url)
            .header("Authorization", auth)
            .json(&body)
            .send()
            .await?;

        parse_response(resp).await
    }
}
