use derive_empty_traits::EmptyTraits;
use resolver_api::Resolve;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;

use crate::entities::{I64, onboarding_key::OnboardingKey};

use super::KomodoWriteRequest;

//

/// **Admin only.** Create a Server onboarding key.
/// Response: [CreateOnboardingKeyResponse].
///
/// Note. The 'periphery_public_key' on default Server config will
/// be overridden with the actual public key once its generated by Periphery
/// as part of the onboarding flow.
#[typeshare]
#[derive(
  Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
)]
#[empty_traits(KomodoWriteRequest)]
#[response(CreateOnboardingKeyResponse)]
#[error(serror::Error)]
pub struct CreateOnboardingKey {
  /// The name for the creation key
  pub name: String,
  /// A unix timestamp in millseconds specifying api key expire time.
  /// Default is 0, which means no expiry.
  #[serde(default)]
  pub expires: I64,
  /// Optionally specify an existing private key, otherwise
  /// generate fresh key.
  pub private_key: Option<String>,
  /// Default tags to apply to Servers created using this key.
  #[serde(default)]
  pub tags: Vec<String>,
  /// Optional. New Servers copy this Server's config.
  #[serde(default)]
  pub copy_server: String,
  /// Optional. Whether to also create a Builder for the Server.
  #[serde(default)]
  pub create_builder: bool,
}

/// The response for [CreateServerOnboardingKey]
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CreateOnboardingKeyResponse {
  /// pkcs8 encoded private key
  pub private_key: String,
  /// The created ServerOnboardingKey
  pub created: OnboardingKey,
}

//

/// **Admin only.** Delete an onboarding key.
/// Response: The deleted [OnboardingKey].
#[typeshare]
#[derive(
  Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
)]
#[empty_traits(KomodoWriteRequest)]
#[response(UpdateOnboardingKeyResponse)]
#[error(serror::Error)]
pub struct UpdateOnboardingKey {
  /// The onboarding public key.
  pub public_key: String,
  /// Update the key enabled state.
  pub enabled: Option<bool>,
  /// Update the key name
  pub name: Option<String>,
  /// Update the onboarding key expire time.
  pub expires: Option<I64>,
  /// Update the tags
  pub tags: Option<Vec<String>>,
  /// Update the copy server
  pub copy_server: Option<String>,
  /// Update whether to create Builder
  pub create_builder: Option<bool>,
}

impl UpdateOnboardingKey {
  pub fn is_none(&self) -> bool {
    self.enabled.is_none()
      && self.name.is_none()
      && self.expires.is_none()
      && self.tags.is_none()
      && self.copy_server.is_none()
      && self.create_builder.is_none()
  }
}

#[typeshare]
pub type UpdateOnboardingKeyResponse = OnboardingKey;

//

/// **Admin only.** Delete an onboarding key.
/// Response: The deleted [OnboardingKey].
#[typeshare]
#[derive(
  Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
)]
#[empty_traits(KomodoWriteRequest)]
#[response(DeleteOnboardingKeyResponse)]
#[error(serror::Error)]
pub struct DeleteOnboardingKey {
  pub public_key: String,
}

#[typeshare]
pub type DeleteOnboardingKeyResponse = OnboardingKey;
