/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use clap::Subcommand;
use crate::entities::{CertType, ContentType, UpdateCertType, DeleteType, NonceType, PolicyDeleteType, TokenFormat};

#[derive(Subcommand)]
pub enum CertificateCommands {
    /// Insert certificate and revoked certificate
    Set {
        /// Certificate name, default the file name
        #[clap(short, long)]
        name: Option<String>,

        /// Certificate description
        #[clap(short, long)]
        description: Option<String>,

        /// Certificate type
        #[clap(long = "cert-type", required = true, value_enum, num_args = 1.., value_delimiter = ',')]
        cert_type: Vec<CertType>,

        /// Certificate content, starting with @ indicates the file path
        #[clap(long, allow_hyphen_values = true)]
        content: Option<String>,

        /// Certificate revoked list content, starting with @ indicates the file path
        #[clap(short, long, allow_hyphen_values = true)]
        crl_content: Option<String>,

        /// Is default certificate, default is 'No'
        #[clap(short, long)]
        is_default: bool,
    },

    /// Delete certificate
    Delete {
        /// Delete type
        #[clap(short, long = "delete-type", value_enum)]
        delete_type: Option<DeleteType>,

        /// Certificate id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Certificate type
        #[clap(short, long = "cert-type", value_enum)]
        cert_type: Option<CertType>,
    },

    /// Update certificate information
    Update {
        /// Certificate id
        #[clap(long, required = true)]
        id: String,

        /// Certificate name
        #[clap(short, long)]
        name: Option<String>,

        /// Certificate description
        #[clap(short, long)]
        description: Option<String>,

        /// Certificate type
        #[clap(short, long = "cert-type", value_enum, num_args = 1.., value_delimiter = ',')]
        cert_type: Option<Vec<UpdateCertType>>,

        /// Is default certificate
        #[clap(short, long)]
        is_default: Option<bool>,
    },

    /// Query certificate information and revocation status
    Get {
        /// Certificate type
        #[clap(short, long = "cert-type", value_enum)]
        cert_type: Option<CertType>,

        /// Certificate id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Page size (1-10, server default 10 when omitted)
        #[clap(long)]
        limit: Option<i64>,

        /// Row offset (0-100000, server default 0 when omitted)
        #[clap(long)]
        offset: Option<i64>,
    },
}

#[derive(Subcommand)]
pub enum PolicyCommands {
    /// Insert policy
    Set {
        /// Policy name, default the file name
        #[clap(short, long)]
        name: Option<String>,

        /// Policy description
        #[clap(short, long)]
        description: Option<String>,

        /// Applicable types of challenge plugins: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, cca, tpm, dice
        #[clap(short = 't', long = "attester-types", value_delimiter = ',')]
        attester_type: Vec<String>,

        /// Content type
        #[clap(long = "content-type", required = true, value_enum)]
        content_type: ContentType,

        /// Policy content, starting with @ indicates the file path
        #[clap(long, required = true)]
        content: String,

        /// Is default policy, default is 'No'
        #[clap(short, long)]
        is_default: bool,
    },
    /// Delete policy
    Delete {
        /// Delete type
        #[clap(short, long = "delete-type", required = true, value_enum)]
        delete_type: PolicyDeleteType,

        /// Policy id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Applicable type of challenge plugin: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee
        #[clap(short = 't', long = "attester-type")]
        attester_type: Option<String>,
    },
    /// Update policy information
    Update {
        /// Policy id
        #[clap(long, required = true)]
        id: String,

        /// Policy name
        #[clap(short, long)]
        name: Option<String>,

        /// Policy description
        #[clap(short, long)]
        description: Option<String>,

        /// Applicable types of challenge plugins: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, cca, tpm, dice
        #[clap(short = 't', long = "attester-types", value_delimiter = ',')]
        attester_type: Option<Vec<String>>,

        /// Content type
        #[clap(long, value_enum)]
        content_type: Option<ContentType>,

        /// Policy content, starting with @ indicates the file path
        #[clap(long)]
        content: Option<String>,

        /// Is default policy, default is 'No'
        #[clap(short, long)]
        is_default: Option<bool>,
    },
    /// Query policy information
    Get {
        /// Applicable types of challenge plugins: `tpm_ima`/`tpm_boot`/`virt_cca`/`dice`
        #[clap(short, long)]
        attester_type: Option<String>,

        /// Policy id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Page size (1-10, server default 10 when omitted)
        #[clap(long)]
        limit: Option<i64>,

        /// Row offset (0-100000, server default 0 when omitted)
        #[clap(long)]
        offset: Option<i64>,
    },
}

#[derive(Subcommand)]
pub enum RegisterCommands {
    /// New register operation
    New {
        /// output credentials only to console
        #[clap(short = 'n', long)]
        nowrite: bool,
    },
    /// Refresh register information
    Refresh {
        /// User-Id for refresh operation
        #[clap(short, long)]
        user: Option<String>,

        /// API credential for refresh operation
        #[clap(short = 'k', long = "apikey")]
        apikey: Option<String>,

        /// output credentials only to console
        #[clap(short = 'n', long)]
        nowrite: bool,
    },
}

#[derive(Subcommand)]
pub enum BaselineCommands {
    /// Insert baseline
    Set {
        /// Baseline name, default the file name
        #[clap(short, long)]
        name: Option<String>,

        /// Baseline description
        #[clap(short, long)]
        description: Option<String>,

        /// Applicable type of challenge plugin: tpm_ima (default), tpm_boot, virt_cca, ascend_npu, itrustee, tpm, cca
        /// Default to tpm_ima as it's the most commonly used for baseline measurements
        #[clap(short = 't', long = "attester-type", default_value = "tpm_ima")]
        attester_type: String,

        /// Baseline content, starting with @ indicates the file path
        #[clap(short, long, required = true)]
        content: String,

        /// Content type: jwt or base64, default jwt
        #[clap(long = "content-type")]
        content_type: Option<String>,

        /// Is default baseline, default is 'No'
        #[clap(short, long)]
        is_default: bool,
    },
    /// Delete baseline
    Delete {
        /// Delete type
        #[clap(short, long = "delete-type", required = true, value_enum)]
        delete_type: DeleteType,

        /// Baseline id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Applicable type of challenge plugin: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, cca, tpm
        #[clap(short = 't', long = "attester-type")]
        attester_type: Option<String>,
    },
    /// Update baseline information
    Update {
        /// Baseline id
        #[clap(long, required = true)]
        id: String,

        /// Baseline name
        #[clap(short, long)]
        name: Option<String>,

        /// Baseline description
        #[clap(short, long)]
        description: Option<String>,

        /// Applicable type of challenge plugin: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, cca, tpm
        #[clap(short = 't', long = "attester-type")]
        attester_type: Option<String>,

        /// Baseline content, starting with @ indicates the file path
        #[clap(short, long)]
        content: Option<String>,

        /// Content type: jwt or base64, default jwt
        #[clap(long = "content-type")]
        content_type: Option<String>,

        /// Is default baseline, default is 'No'
        #[clap(short, long)]
        is_default: Option<bool>,
    },
    /// Query baseline information
    Get {
        /// Applicable type of challenge plugin: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, tpm, cca
        #[clap(short = 't', long = "attester-type")]
        attester_type: Option<String>,

        /// Baseline id list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        ids: Option<Vec<String>>,

        /// Page size (1-10, server default 10 when omitted)
        #[clap(long)]
        limit: Option<i64>,

        /// Row offset (0-100000, server default 0 when omitted)
        #[clap(long)]
        offset: Option<i64>,
    },
}

#[derive(Subcommand)]
pub enum NonceCommands {
    /// Get nonce
    Get {
        /// Output file address
        #[clap(short, long)]
        out: Option<String>,
    },
}

#[derive(Subcommand)]
pub enum EvidenceCommands {
    /// Get evidence
    Get {
        /// Nonce type
        #[clap(short = 's', long = "nonce-type", required = true, value_enum)]
        nonce_type: NonceType,

        /// Nonce, base64 encoded string
        #[clap(short = 'n', long)]
        nonce: Option<String>,

        /// Output file path
        #[clap(short = 'o', long, required = true)]
        out: String,

        /// user data
        #[clap(short = 'd', long)]
        attester_data: Option<serde_json::Value>,

        /// Applicable types of challenge plugins: tpm_boot, tpm_ima, virt_cca, ascend_npu, itrustee, cca, tpm, dice
        #[clap(short = 't', long = "attester-types", value_delimiter = ',')]
        attester_types: Option<Vec<String>>,

        /// Token format, default to eat
        #[clap(short = 'f', long = "token-format", value_enum)]
        token_format: Option<TokenFormat>,

        /// Attester ids, such as uuid of TA in itrustee.
        #[clap(short = 'i', long, value_delimiter = ',')]
        attester_ids: Option<Vec<String>>,
    },
}

#[derive(Subcommand)]
pub enum TokenCommands {
    /// Verify token
    Verify {
        /// Token file address
        #[clap(short, long)]
        file: Option<String>,

        /// Token list
        #[clap(short, long, num_args = 1.., value_delimiter = ',')]
        token: Option<Vec<String>>,
    },
}