// this file is @generated
use clap::{Args, Subcommand};
use svix::api::Svix;
#[allow(unused_imports)]
use svix::models::*;

#[derive(Args, Clone)]
pub struct IngestSourceListOptions {
    /// Limit the number of returned items
    #[arg(long)]
    pub limit: Option<u64>,

    /// The iterator returned from a prior invocation
    #[arg(long)]
    pub iterator: Option<String>,

    /// The sorting order of the returned items
    #[arg(long)]
    pub order: Option<Ordering>,
}

impl From<IngestSourceListOptions> for svix::api::IngestSourceListOptions {
    fn from(value: IngestSourceListOptions) -> Self {
        let IngestSourceListOptions {
            limit,
            iterator,
            order,
        } = value;
        Self {
            limit,
            iterator,
            order,
        }
    }
}

#[derive(Args, Clone)]
pub struct IngestSourceCreateOptions {
    #[arg(long)]
    pub idempotency_key: Option<String>,
}

impl From<IngestSourceCreateOptions> for svix::api::IngestSourceCreateOptions {
    fn from(value: IngestSourceCreateOptions) -> Self {
        let IngestSourceCreateOptions { idempotency_key } = value;
        Self { idempotency_key }
    }
}

#[derive(Args, Clone)]
pub struct IngestSourceRotateTokenOptions {
    #[arg(long)]
    pub idempotency_key: Option<String>,
}

impl From<IngestSourceRotateTokenOptions> for svix::api::IngestSourceRotateTokenOptions {
    fn from(value: IngestSourceRotateTokenOptions) -> Self {
        let IngestSourceRotateTokenOptions { idempotency_key } = value;
        Self { idempotency_key }
    }
}

#[derive(Args)]
#[command(args_conflicts_with_subcommands = true, flatten_help = true)]
pub struct IngestSourceArgs {
    #[command(subcommand)]
    pub command: IngestSourceCommands,
}

#[allow(clippy::large_enum_variant)]
#[derive(Subcommand)]
pub enum IngestSourceCommands {
    /// List of all the organization's Ingest Sources.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source list\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    #[command(after_help = "Example response:
{
  \"data\": [{\"...\": \"...\"}],
  \"iterator\": \"iterator\",
  \"prevIterator\": \"-iterator\",
  \"done\": true
}\n")]
    List {
        #[clap(flatten)]
        options: IngestSourceListOptions,
    },
    /// Create Ingest Source.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source create {...}\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    #[command(after_help = "Example body:
{
  \"name\": \"...\",
  \"uid\": \"unique-identifier\",
  \"metadata\": {\"key\": \"...\"}
}\n\nExample response:
{
  \"id\": \"src_2yZwUhtgs5Ai8T9yRQJXA\",
  \"uid\": \"unique-identifier\",
  \"name\": \"...\",
  \"ingestUrl\": \"...\",
  \"createdAt\": \"2030-01-01T00:00:00Z\",
  \"updatedAt\": \"2030-01-01T00:00:00Z\",
  \"metadata\": {\"key\": \"...\"}
}\n")]
    Create {
        ingest_source_in: crate::json::JsonOf<IngestSourceIn>,
        #[clap(flatten)]
        options: IngestSourceCreateOptions,
    },
    /// Get an Ingest Source by id or uid.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source get src_abc000000000000000000\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    #[command(after_help = "Example response:
{
  \"id\": \"src_2yZwUhtgs5Ai8T9yRQJXA\",
  \"uid\": \"unique-identifier\",
  \"name\": \"...\",
  \"ingestUrl\": \"...\",
  \"createdAt\": \"2030-01-01T00:00:00Z\",
  \"updatedAt\": \"2030-01-01T00:00:00Z\",
  \"metadata\": {\"key\": \"...\"}
}\n")]
    Get { source_id: String },
    /// Create or update an Ingest Source.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source upsert src_abc000000000000000000 {...}\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    #[command(after_help = "Example body:
{
  \"name\": \"...\",
  \"uid\": \"unique-identifier\",
  \"metadata\": {\"key\": \"...\"}
}\n\nExample response:
{
  \"id\": \"src_2yZwUhtgs5Ai8T9yRQJXA\",
  \"uid\": \"unique-identifier\",
  \"name\": \"...\",
  \"ingestUrl\": \"...\",
  \"createdAt\": \"2030-01-01T00:00:00Z\",
  \"updatedAt\": \"2030-01-01T00:00:00Z\",
  \"metadata\": {\"key\": \"...\"}
}\n")]
    Upsert {
        source_id: String,
        ingest_source_in: crate::json::JsonOf<IngestSourceIn>,
    },
    /// Delete an Ingest Source.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source delete src_abc000000000000000000\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    Delete { source_id: String },
    /// Rotate the Ingest Source's Url Token.
    ///
    /// This will rotate the ingest source's token, which is used to
    /// construct the unique `ingestUrl` for the source. Previous tokens
    /// will remain valid for 48 hours after rotation. The token can be
    /// rotated a maximum of three times within the 48-hour period.
    #[command(help_template = concat!(
            "{about-with-newline}\n",
            "{usage-heading} {usage}\n\n",
            "Example: svix ingest source rotate-token src_abc000000000000000000\n",
            "{after-help}",
            "\n",
            "{all-args}",
        ))]
    #[command(after_help = "Example response:
{
  \"ingestUrl\": \"...\"
}\n")]
    RotateToken {
        source_id: String,
        #[clap(flatten)]
        options: IngestSourceRotateTokenOptions,
    },
}

impl IngestSourceCommands {
    pub async fn exec(
        self,
        client: &Svix,
        color_mode: colored_json::ColorMode,
    ) -> anyhow::Result<()> {
        match self {
            Self::List { options } => {
                let resp = client.ingest().source().list(Some(options.into())).await?;
                crate::json::print_json_output(&resp, color_mode)?;
            }
            Self::Create {
                ingest_source_in,
                options,
            } => {
                let resp = client
                    .ingest()
                    .source()
                    .create(ingest_source_in.into_inner(), Some(options.into()))
                    .await?;
                crate::json::print_json_output(&resp, color_mode)?;
            }
            Self::Get { source_id } => {
                let resp = client.ingest().source().get(source_id).await?;
                crate::json::print_json_output(&resp, color_mode)?;
            }
            Self::Upsert {
                source_id,
                ingest_source_in,
            } => {
                let resp = client
                    .ingest()
                    .source()
                    .upsert(source_id, ingest_source_in.into_inner())
                    .await?;
                crate::json::print_json_output(&resp, color_mode)?;
            }
            Self::Delete { source_id } => {
                client.ingest().source().delete(source_id).await?;
            }
            Self::RotateToken { source_id, options } => {
                let resp = client
                    .ingest()
                    .source()
                    .rotate_token(source_id, Some(options.into()))
                    .await?;
                crate::json::print_json_output(&resp, color_mode)?;
            }
        }

        Ok(())
    }
}
