use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[allow(unused_imports)]
use super::*;
/// The details of the volume to create. For CreateVolume operation, this field is required in the request, see {@link #createVolume(CreateVolumeRequest) createVolume}.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateVolumeDetails {
    /// The OCID of the compartment that contains the volume.
    pub compartment_id: String,

    /// The availability domain of the volume. Omissible for cloning a volume. The new volume will be created in the availability domain of the source volume. <p> Example: {@code Uocm:PHX-AD-1}
    #[serde(skip_serializing_if = "Option::is_none")]
    pub availability_domain: Option<String>,

    /// If provided, specifies the ID of the volume backup policy to assign to the newly created volume. If omitted, no policy will be assigned.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub backup_policy_id: Option<String>,

    /// Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags](https://docs.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). <p> Example: {@code {\"Operations\": {\"CostCenter\": \"42\"}}}
    #[serde(skip_serializing_if = "Option::is_none")]
    pub defined_tags: Option<HashMap<String, HashMap<String, serde_json::Value>>>,

    /// A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<String>,

    /// Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags](https://docs.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). <p> Example: {@code {\"Department\": \"Finance\"}}
    #[serde(skip_serializing_if = "Option::is_none")]
    pub freeform_tags: Option<HashMap<String, String>>,

    /// The OCID of the Vault service key to assign as the master encryption key for the volume.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kms_key_id: Option<String>,

    /// The number of volume performance units (VPUs) that will be applied to this volume per GB, representing the Block Volume service's elastic performance options. See [Block Volume Performance Levels](https://docs.oracle.com/iaas/Content/Block/Concepts/blockvolumeperformance.htm#perf_levels) for more information. <p> Allowed values: <p> {@code 0}: Represents Lower Cost option. <p> {@code 10}: Represents Balanced option. <p> {@code 20}: Represents Higher Performance option. <p> {@code 30}-{@code 120}: Represents the Ultra High Performance option. <p> For performance autotune enabled volumes, it would be the Default(Minimum) VPUs/GB. Note: Numbers greater than Number.MAX_SAFE_INTEGER will result in rounding issues.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub vpus_per_gb: Option<i64>,

    /// The clusterPlacementGroup Id of the volume for volume placement.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cluster_placement_group_id: Option<String>,

    /// The size of the volume in GBs. Note: Numbers greater than Number.MAX_SAFE_INTEGER will result in rounding issues.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub size_in_gbs: Option<i64>,

    /// The size of the volume in MBs. The value must be a multiple of 1024. This field is deprecated. Use sizeInGBs instead. Note: Numbers greater than Number.MAX_SAFE_INTEGER will result in rounding issues.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub size_in_mbs: Option<i64>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub source_details: Option<VolumeSourceFromBlockVolumeReplicaDetails>,

    /// The OCID of the volume backup from which the data should be restored on the newly created volume. This field is deprecated. Use the sourceDetails field instead to specify the backup for the volume.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub volume_backup_id: Option<String>,

    /// Specifies whether the auto-tune performance is enabled for this volume. This field is deprecated. Use the {@code DetachedVolumeAutotunePolicy} instead to enable the volume for detached autotune.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_auto_tune_enabled: Option<bool>,

    /// The list of block volume replicas to be enabled for this volume in the specified destination availability domains.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub block_volume_replicas: Option<Vec<BlockVolumeReplicaDetails>>,

    /// The list of autotune policies to be enabled for this volume.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub autotune_policies: Option<Vec<AutotunePolicy>>,

    /// The OCID of the Vault service key which is the master encryption key for the block volume cross region backups, which will be used in the destination region to encrypt the backup's encryption keys. For more information about the Vault service and encryption keys, see [Overview of Vault service](https://docs.oracle.com/iaas/Content/KeyManagement/Concepts/keyoverview.htm) and [Using Keys](https://docs.oracle.com/iaas/Content/KeyManagement/Tasks/usingkeys.htm).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub xrc_kms_key_id: Option<String>,

    /// When set to true, enables SCSI Persistent Reservation (SCSI PR) for the volume. For more information, see [Persistent Reservations](https://docs.oracle.com/iaas/Content/Block/Concepts/persistent-reservations.htm).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_reservations_enabled: Option<bool>,
}

/// Required fields for CreateVolumeDetails
pub struct CreateVolumeDetailsRequired {
    /// The OCID of the compartment that contains the volume.
    pub compartment_id: String,
}

impl CreateVolumeDetails {
    /// Create a new CreateVolumeDetails with required fields
    pub fn new(required: CreateVolumeDetailsRequired) -> Self {
        Self {
            compartment_id: required.compartment_id,

            availability_domain: None,

            backup_policy_id: None,

            defined_tags: None,

            display_name: None,

            freeform_tags: None,

            kms_key_id: None,

            vpus_per_gb: None,

            cluster_placement_group_id: None,

            size_in_gbs: None,

            size_in_mbs: None,

            source_details: None,

            volume_backup_id: None,

            is_auto_tune_enabled: None,

            block_volume_replicas: None,

            autotune_policies: None,

            xrc_kms_key_id: None,

            is_reservations_enabled: None,
        }
    }

    /// Set availability_domain
    pub fn set_availability_domain(mut self, value: Option<String>) -> Self {
        self.availability_domain = value;
        self
    }

    /// Set backup_policy_id
    pub fn set_backup_policy_id(mut self, value: Option<String>) -> Self {
        self.backup_policy_id = value;
        self
    }

    /// Set compartment_id
    pub fn set_compartment_id(mut self, value: String) -> Self {
        self.compartment_id = value;
        self
    }

    /// Set defined_tags
    pub fn set_defined_tags(
        mut self,
        value: Option<HashMap<String, HashMap<String, serde_json::Value>>>,
    ) -> Self {
        self.defined_tags = value;
        self
    }

    /// Set display_name
    pub fn set_display_name(mut self, value: Option<String>) -> Self {
        self.display_name = value;
        self
    }

    /// Set freeform_tags
    pub fn set_freeform_tags(mut self, value: Option<HashMap<String, String>>) -> Self {
        self.freeform_tags = value;
        self
    }

    /// Set kms_key_id
    pub fn set_kms_key_id(mut self, value: Option<String>) -> Self {
        self.kms_key_id = value;
        self
    }

    /// Set vpus_per_gb
    pub fn set_vpus_per_gb(mut self, value: Option<i64>) -> Self {
        self.vpus_per_gb = value;
        self
    }

    /// Set cluster_placement_group_id
    pub fn set_cluster_placement_group_id(mut self, value: Option<String>) -> Self {
        self.cluster_placement_group_id = value;
        self
    }

    /// Set size_in_gbs
    pub fn set_size_in_gbs(mut self, value: Option<i64>) -> Self {
        self.size_in_gbs = value;
        self
    }

    /// Set size_in_mbs
    pub fn set_size_in_mbs(mut self, value: Option<i64>) -> Self {
        self.size_in_mbs = value;
        self
    }

    /// Set source_details
    pub fn set_source_details(
        mut self,
        value: Option<VolumeSourceFromBlockVolumeReplicaDetails>,
    ) -> Self {
        self.source_details = value;
        self
    }

    /// Set volume_backup_id
    pub fn set_volume_backup_id(mut self, value: Option<String>) -> Self {
        self.volume_backup_id = value;
        self
    }

    /// Set is_auto_tune_enabled
    pub fn set_is_auto_tune_enabled(mut self, value: Option<bool>) -> Self {
        self.is_auto_tune_enabled = value;
        self
    }

    /// Set block_volume_replicas
    pub fn set_block_volume_replicas(
        mut self,
        value: Option<Vec<BlockVolumeReplicaDetails>>,
    ) -> Self {
        self.block_volume_replicas = value;
        self
    }

    /// Set autotune_policies
    pub fn set_autotune_policies(mut self, value: Option<Vec<AutotunePolicy>>) -> Self {
        self.autotune_policies = value;
        self
    }

    /// Set xrc_kms_key_id
    pub fn set_xrc_kms_key_id(mut self, value: Option<String>) -> Self {
        self.xrc_kms_key_id = value;
        self
    }

    /// Set is_reservations_enabled
    pub fn set_is_reservations_enabled(mut self, value: Option<bool>) -> Self {
        self.is_reservations_enabled = value;
        self
    }

    /// Set availability_domain (unwraps Option)
    pub fn with_availability_domain(mut self, value: impl Into<String>) -> Self {
        self.availability_domain = Some(value.into());
        self
    }

    /// Set backup_policy_id (unwraps Option)
    pub fn with_backup_policy_id(mut self, value: impl Into<String>) -> Self {
        self.backup_policy_id = Some(value.into());
        self
    }

    /// Set defined_tags (unwraps Option)
    pub fn with_defined_tags(
        mut self,
        value: HashMap<String, HashMap<String, serde_json::Value>>,
    ) -> Self {
        self.defined_tags = Some(value);
        self
    }

    /// Set display_name (unwraps Option)
    pub fn with_display_name(mut self, value: impl Into<String>) -> Self {
        self.display_name = Some(value.into());
        self
    }

    /// Set freeform_tags (unwraps Option)
    pub fn with_freeform_tags(mut self, value: HashMap<String, String>) -> Self {
        self.freeform_tags = Some(value);
        self
    }

    /// Set kms_key_id (unwraps Option)
    pub fn with_kms_key_id(mut self, value: impl Into<String>) -> Self {
        self.kms_key_id = Some(value.into());
        self
    }

    /// Set vpus_per_gb (unwraps Option)
    pub fn with_vpus_per_gb(mut self, value: i64) -> Self {
        self.vpus_per_gb = Some(value);
        self
    }

    /// Set cluster_placement_group_id (unwraps Option)
    pub fn with_cluster_placement_group_id(mut self, value: impl Into<String>) -> Self {
        self.cluster_placement_group_id = Some(value.into());
        self
    }

    /// Set size_in_gbs (unwraps Option)
    pub fn with_size_in_gbs(mut self, value: i64) -> Self {
        self.size_in_gbs = Some(value);
        self
    }

    /// Set size_in_mbs (unwraps Option)
    pub fn with_size_in_mbs(mut self, value: i64) -> Self {
        self.size_in_mbs = Some(value);
        self
    }

    /// Set source_details (unwraps Option)
    pub fn with_source_details(mut self, value: VolumeSourceFromBlockVolumeReplicaDetails) -> Self {
        self.source_details = Some(value);
        self
    }

    /// Set volume_backup_id (unwraps Option)
    pub fn with_volume_backup_id(mut self, value: impl Into<String>) -> Self {
        self.volume_backup_id = Some(value.into());
        self
    }

    /// Set is_auto_tune_enabled (unwraps Option)
    pub fn with_is_auto_tune_enabled(mut self, value: bool) -> Self {
        self.is_auto_tune_enabled = Some(value);
        self
    }

    /// Set block_volume_replicas (unwraps Option)
    pub fn with_block_volume_replicas(mut self, value: Vec<BlockVolumeReplicaDetails>) -> Self {
        self.block_volume_replicas = Some(value);
        self
    }

    /// Set autotune_policies (unwraps Option)
    pub fn with_autotune_policies(mut self, value: Vec<AutotunePolicy>) -> Self {
        self.autotune_policies = Some(value);
        self
    }

    /// Set xrc_kms_key_id (unwraps Option)
    pub fn with_xrc_kms_key_id(mut self, value: impl Into<String>) -> Self {
        self.xrc_kms_key_id = Some(value.into());
        self
    }

    /// Set is_reservations_enabled (unwraps Option)
    pub fn with_is_reservations_enabled(mut self, value: bool) -> Self {
        self.is_reservations_enabled = Some(value);
        self
    }
}
