//! The type that represents a response of `oauth.v2.access`.
//!
//! <https://api.slack.com/methods/oauth.v2.access>

use crate::generated::oauth_v2_access::OauthV2AccessResponse as Generated;
use crate::Error;
use serde::Deserialize;

/// The type that represents a response of `oauth.v2.access`.
///
/// <https://api.slack.com/methods/oauth.v2.access>
#[derive(Deserialize, Debug)]
pub struct OauthV2AccessResponse(Generated);

impl OauthV2AccessResponse {
    /// Converts to generated type.
    pub fn into_inner(self) -> Generated {
        self.0
    }

    /// Takes `access_token`.
    pub fn access_token(&self) -> Option<&str> {
        self.0.access_token.as_deref()
    }

    /// Takes `id` in `team`.
    pub fn team_id(&self) -> Option<&str> {
        match &self.0.team {
            None => None,
            Some(team) => team.id.as_deref(),
        }
    }
}

impl TryFrom<serde_json::Value> for OauthV2AccessResponse {
    type Error = Error;

    fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
        serde_json::from_value(value).map_err(Error::DeserializeJson)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_de_oauth_v2_access_response() -> anyhow::Result<()> {
        let testdata = r#"{
            "ok": true,
            "access_token": "xoxb-17653672481-19874698323-pdFZKVeTuE8sk7oOcBrzbqgy",
            "token_type": "bot",
            "scope": "commands,incoming-webhook",
            "bot_user_id": "U0KRQLJ9H",
            "app_id": "A0KRD7HC3",
            "team": {
                "name": "Slack Softball Team",
                "id": "T9TK3CUKW"
            },
            "enterprise": {
                "name": "slack-sports",
                "id": "E12345678"
            },
            "authed_user": {
                "id": "U1234",
                "scope": "chat:write",
                "access_token": "xoxp-1234",
                "token_type": "user"
            }
        }"#;
        let deserialized: OauthV2AccessResponse = serde_json::from_str(testdata)?;

        assert_eq!(
            deserialized.access_token().unwrap(),
            "xoxb-17653672481-19874698323-pdFZKVeTuE8sk7oOcBrzbqgy"
        );
        assert_eq!(deserialized.team_id().unwrap(), "T9TK3CUKW");

        let deserialized = deserialized.into_inner();
        assert_eq!(
            deserialized.access_token.unwrap(),
            "xoxb-17653672481-19874698323-pdFZKVeTuE8sk7oOcBrzbqgy"
        );
        let team = deserialized.team.unwrap();
        assert_eq!(team.id.unwrap(), "T9TK3CUKW");

        Ok(())
    }
}
