use serde::{Deserialize, Serialize};

use crate::{
    ids::{AuthProfileId, WorkspaceId},
    protocol::AuthKind,
};

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SecretRef(pub String);

impl SecretRef {
    pub fn new(value: impl Into<String>) -> Self {
        Self(value.into())
    }

    pub fn as_str(&self) -> &str {
        &self.0
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BearerAuthConfig {
    pub header_name: String,
    pub secret_ref: SecretRef,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BasicAuthConfig {
    pub username_secret_ref: SecretRef,
    pub password_secret_ref: SecretRef,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ApiKeyHeaderAuthConfig {
    pub header_name: String,
    pub secret_ref: SecretRef,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ApiKeyQueryAuthConfig {
    pub param_name: String,
    pub secret_ref: SecretRef,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthConfig {
    Bearer(BearerAuthConfig),
    Basic(BasicAuthConfig),
    ApiKeyHeader(ApiKeyHeaderAuthConfig),
    ApiKeyQuery(ApiKeyQueryAuthConfig),
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuthProfile {
    pub id: AuthProfileId,
    pub workspace_id: WorkspaceId,
    pub name: String,
    pub kind: AuthKind,
    pub config: AuthConfig,
    pub created_at: String,
    pub updated_at: String,
}
