// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.resourcemanager.networkcloud.fluent.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.util.logging.ClientLogger;
import com.azure.resourcemanager.networkcloud.models.ImageRepositoryCredentials;
import com.azure.resourcemanager.networkcloud.models.NetworkAttachment;
import com.azure.resourcemanager.networkcloud.models.SshPublicKey;
import com.azure.resourcemanager.networkcloud.models.StorageProfile;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineBootMethod;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineDetailedStatus;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineDeviceModelType;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineIsolateEmulatorThread;
import com.azure.resourcemanager.networkcloud.models.VirtualMachinePlacementHint;
import com.azure.resourcemanager.networkcloud.models.VirtualMachinePowerState;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineProvisioningState;
import com.azure.resourcemanager.networkcloud.models.VirtualMachineVirtioInterfaceType;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

/** VirtualMachineProperties represents the properties of the virtual machine. */
@Fluent
public final class VirtualMachineProperties {
    /*
     * The name of the administrator to which the ssh public keys will be added into the authorized keys.
     */
    @JsonProperty(value = "adminUsername", required = true)
    private String adminUsername;

    /*
     * The cluster availability zone containing this virtual machine.
     */
    @JsonProperty(value = "availabilityZone", access = JsonProperty.Access.WRITE_ONLY)
    private String availabilityZone;

    /*
     * The resource ID of the bare metal machine the virtual machine has landed to.
     */
    @JsonProperty(value = "bareMetalMachineId", access = JsonProperty.Access.WRITE_ONLY)
    private String bareMetalMachineId;

    /*
     * Selects the boot method for the virtual machine.
     */
    @JsonProperty(value = "bootMethod")
    private VirtualMachineBootMethod bootMethod;

    /*
     * NetworkAttachment represents the single network attachment.
     *
     * The cloud service network that provides platform-level services for the virtual machine.
     */
    @JsonProperty(value = "cloudServicesNetworkAttachment", required = true)
    private NetworkAttachment cloudServicesNetworkAttachment;

    /*
     * The resource ID of the cluster the virtual machine is created for.
     */
    @JsonProperty(value = "clusterId", access = JsonProperty.Access.WRITE_ONLY)
    private String clusterId;

    /*
     * The number of CPU cores in the virtual machine.
     */
    @JsonProperty(value = "cpuCores", required = true)
    private long cpuCores;

    /*
     * The more detailed status of the virtual machine.
     */
    @JsonProperty(value = "detailedStatus", access = JsonProperty.Access.WRITE_ONLY)
    private VirtualMachineDetailedStatus detailedStatus;

    /*
     * The descriptive message about the current detailed status.
     */
    @JsonProperty(value = "detailedStatusMessage", access = JsonProperty.Access.WRITE_ONLY)
    private String detailedStatusMessage;

    /*
     * Field Deprecated, the value will be ignored if provided. The indicator of whether one of the specified CPU cores
     * is isolated to run the emulator thread for this virtual machine.
     */
    @JsonProperty(value = "isolateEmulatorThread")
    private VirtualMachineIsolateEmulatorThread isolateEmulatorThread;

    /*
     * The memory size of the virtual machine in GB.
     */
    @JsonProperty(value = "memorySizeGB", required = true)
    private long memorySizeGB;

    /*
     * The list of network attachments to the virtual machine.
     */
    @JsonProperty(value = "networkAttachments")
    private List<NetworkAttachment> networkAttachments;

    /*
     * The Base64 encoded cloud-init network data.
     */
    @JsonProperty(value = "networkData")
    private String networkData;

    /*
     * The scheduling hints for the virtual machine.
     */
    @JsonProperty(value = "placementHints")
    private List<VirtualMachinePlacementHint> placementHints;

    /*
     * The power state of the virtual machine.
     */
    @JsonProperty(value = "powerState", access = JsonProperty.Access.WRITE_ONLY)
    private VirtualMachinePowerState powerState;

    /*
     * The provisioning state of the virtual machine.
     */
    @JsonProperty(value = "provisioningState", access = JsonProperty.Access.WRITE_ONLY)
    private VirtualMachineProvisioningState provisioningState;

    /*
     * The list of ssh public keys. Each key will be added to the virtual machine using the cloud-init
     * ssh_authorized_keys mechanism for the adminUsername.
     */
    @JsonProperty(value = "sshPublicKeys")
    private List<SshPublicKey> sshPublicKeys;

    /*
     * StorageProfile represents information about a disk.
     *
     * The storage profile that specifies size and other parameters about the disks related to the virtual machine.
     */
    @JsonProperty(value = "storageProfile", required = true)
    private StorageProfile storageProfile;

    /*
     * The Base64 encoded cloud-init user data.
     */
    @JsonProperty(value = "userData")
    private String userData;

    /*
     * Field Deprecated, use virtualizationModel instead. The type of the virtio interface.
     */
    @JsonProperty(value = "virtioInterface")
    private VirtualMachineVirtioInterfaceType virtioInterface;

    /*
     * The type of the device model to use.
     */
    @JsonProperty(value = "vmDeviceModel")
    private VirtualMachineDeviceModelType vmDeviceModel;

    /*
     * The virtual machine image that is currently provisioned to the OS disk, using the full url and tag notation used
     * to pull the image.
     */
    @JsonProperty(value = "vmImage", required = true)
    private String vmImage;

    /*
     * ImageRepositoryCredentials represents the credentials used to login to the image repository.
     *
     * The credentials used to login to the image repository that has access to the specified image.
     */
    @JsonProperty(value = "vmImageRepositoryCredentials")
    private ImageRepositoryCredentials vmImageRepositoryCredentials;

    /*
     * The resource IDs of volumes that are attached to the virtual machine.
     */
    @JsonProperty(value = "volumes", access = JsonProperty.Access.WRITE_ONLY)
    private List<String> volumes;

    /** Creates an instance of VirtualMachineProperties class. */
    public VirtualMachineProperties() {
    }

    /**
     * Get the adminUsername property: The name of the administrator to which the ssh public keys will be added into the
     * authorized keys.
     *
     * @return the adminUsername value.
     */
    public String adminUsername() {
        return this.adminUsername;
    }

    /**
     * Set the adminUsername property: The name of the administrator to which the ssh public keys will be added into the
     * authorized keys.
     *
     * @param adminUsername the adminUsername value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withAdminUsername(String adminUsername) {
        this.adminUsername = adminUsername;
        return this;
    }

    /**
     * Get the availabilityZone property: The cluster availability zone containing this virtual machine.
     *
     * @return the availabilityZone value.
     */
    public String availabilityZone() {
        return this.availabilityZone;
    }

    /**
     * Get the bareMetalMachineId property: The resource ID of the bare metal machine the virtual machine has landed to.
     *
     * @return the bareMetalMachineId value.
     */
    public String bareMetalMachineId() {
        return this.bareMetalMachineId;
    }

    /**
     * Get the bootMethod property: Selects the boot method for the virtual machine.
     *
     * @return the bootMethod value.
     */
    public VirtualMachineBootMethod bootMethod() {
        return this.bootMethod;
    }

    /**
     * Set the bootMethod property: Selects the boot method for the virtual machine.
     *
     * @param bootMethod the bootMethod value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withBootMethod(VirtualMachineBootMethod bootMethod) {
        this.bootMethod = bootMethod;
        return this;
    }

    /**
     * Get the cloudServicesNetworkAttachment property: NetworkAttachment represents the single network attachment.
     *
     * <p>The cloud service network that provides platform-level services for the virtual machine.
     *
     * @return the cloudServicesNetworkAttachment value.
     */
    public NetworkAttachment cloudServicesNetworkAttachment() {
        return this.cloudServicesNetworkAttachment;
    }

    /**
     * Set the cloudServicesNetworkAttachment property: NetworkAttachment represents the single network attachment.
     *
     * <p>The cloud service network that provides platform-level services for the virtual machine.
     *
     * @param cloudServicesNetworkAttachment the cloudServicesNetworkAttachment value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withCloudServicesNetworkAttachment(
        NetworkAttachment cloudServicesNetworkAttachment) {
        this.cloudServicesNetworkAttachment = cloudServicesNetworkAttachment;
        return this;
    }

    /**
     * Get the clusterId property: The resource ID of the cluster the virtual machine is created for.
     *
     * @return the clusterId value.
     */
    public String clusterId() {
        return this.clusterId;
    }

    /**
     * Get the cpuCores property: The number of CPU cores in the virtual machine.
     *
     * @return the cpuCores value.
     */
    public long cpuCores() {
        return this.cpuCores;
    }

    /**
     * Set the cpuCores property: The number of CPU cores in the virtual machine.
     *
     * @param cpuCores the cpuCores value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withCpuCores(long cpuCores) {
        this.cpuCores = cpuCores;
        return this;
    }

    /**
     * Get the detailedStatus property: The more detailed status of the virtual machine.
     *
     * @return the detailedStatus value.
     */
    public VirtualMachineDetailedStatus detailedStatus() {
        return this.detailedStatus;
    }

    /**
     * Get the detailedStatusMessage property: The descriptive message about the current detailed status.
     *
     * @return the detailedStatusMessage value.
     */
    public String detailedStatusMessage() {
        return this.detailedStatusMessage;
    }

    /**
     * Get the isolateEmulatorThread property: Field Deprecated, the value will be ignored if provided. The indicator of
     * whether one of the specified CPU cores is isolated to run the emulator thread for this virtual machine.
     *
     * @return the isolateEmulatorThread value.
     */
    public VirtualMachineIsolateEmulatorThread isolateEmulatorThread() {
        return this.isolateEmulatorThread;
    }

    /**
     * Set the isolateEmulatorThread property: Field Deprecated, the value will be ignored if provided. The indicator of
     * whether one of the specified CPU cores is isolated to run the emulator thread for this virtual machine.
     *
     * @param isolateEmulatorThread the isolateEmulatorThread value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withIsolateEmulatorThread(
        VirtualMachineIsolateEmulatorThread isolateEmulatorThread) {
        this.isolateEmulatorThread = isolateEmulatorThread;
        return this;
    }

    /**
     * Get the memorySizeGB property: The memory size of the virtual machine in GB.
     *
     * @return the memorySizeGB value.
     */
    public long memorySizeGB() {
        return this.memorySizeGB;
    }

    /**
     * Set the memorySizeGB property: The memory size of the virtual machine in GB.
     *
     * @param memorySizeGB the memorySizeGB value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withMemorySizeGB(long memorySizeGB) {
        this.memorySizeGB = memorySizeGB;
        return this;
    }

    /**
     * Get the networkAttachments property: The list of network attachments to the virtual machine.
     *
     * @return the networkAttachments value.
     */
    public List<NetworkAttachment> networkAttachments() {
        return this.networkAttachments;
    }

    /**
     * Set the networkAttachments property: The list of network attachments to the virtual machine.
     *
     * @param networkAttachments the networkAttachments value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withNetworkAttachments(List<NetworkAttachment> networkAttachments) {
        this.networkAttachments = networkAttachments;
        return this;
    }

    /**
     * Get the networkData property: The Base64 encoded cloud-init network data.
     *
     * @return the networkData value.
     */
    public String networkData() {
        return this.networkData;
    }

    /**
     * Set the networkData property: The Base64 encoded cloud-init network data.
     *
     * @param networkData the networkData value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withNetworkData(String networkData) {
        this.networkData = networkData;
        return this;
    }

    /**
     * Get the placementHints property: The scheduling hints for the virtual machine.
     *
     * @return the placementHints value.
     */
    public List<VirtualMachinePlacementHint> placementHints() {
        return this.placementHints;
    }

    /**
     * Set the placementHints property: The scheduling hints for the virtual machine.
     *
     * @param placementHints the placementHints value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withPlacementHints(List<VirtualMachinePlacementHint> placementHints) {
        this.placementHints = placementHints;
        return this;
    }

    /**
     * Get the powerState property: The power state of the virtual machine.
     *
     * @return the powerState value.
     */
    public VirtualMachinePowerState powerState() {
        return this.powerState;
    }

    /**
     * Get the provisioningState property: The provisioning state of the virtual machine.
     *
     * @return the provisioningState value.
     */
    public VirtualMachineProvisioningState provisioningState() {
        return this.provisioningState;
    }

    /**
     * Get the sshPublicKeys property: The list of ssh public keys. Each key will be added to the virtual machine using
     * the cloud-init ssh_authorized_keys mechanism for the adminUsername.
     *
     * @return the sshPublicKeys value.
     */
    public List<SshPublicKey> sshPublicKeys() {
        return this.sshPublicKeys;
    }

    /**
     * Set the sshPublicKeys property: The list of ssh public keys. Each key will be added to the virtual machine using
     * the cloud-init ssh_authorized_keys mechanism for the adminUsername.
     *
     * @param sshPublicKeys the sshPublicKeys value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withSshPublicKeys(List<SshPublicKey> sshPublicKeys) {
        this.sshPublicKeys = sshPublicKeys;
        return this;
    }

    /**
     * Get the storageProfile property: StorageProfile represents information about a disk.
     *
     * <p>The storage profile that specifies size and other parameters about the disks related to the virtual machine.
     *
     * @return the storageProfile value.
     */
    public StorageProfile storageProfile() {
        return this.storageProfile;
    }

    /**
     * Set the storageProfile property: StorageProfile represents information about a disk.
     *
     * <p>The storage profile that specifies size and other parameters about the disks related to the virtual machine.
     *
     * @param storageProfile the storageProfile value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withStorageProfile(StorageProfile storageProfile) {
        this.storageProfile = storageProfile;
        return this;
    }

    /**
     * Get the userData property: The Base64 encoded cloud-init user data.
     *
     * @return the userData value.
     */
    public String userData() {
        return this.userData;
    }

    /**
     * Set the userData property: The Base64 encoded cloud-init user data.
     *
     * @param userData the userData value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withUserData(String userData) {
        this.userData = userData;
        return this;
    }

    /**
     * Get the virtioInterface property: Field Deprecated, use virtualizationModel instead. The type of the virtio
     * interface.
     *
     * @return the virtioInterface value.
     */
    public VirtualMachineVirtioInterfaceType virtioInterface() {
        return this.virtioInterface;
    }

    /**
     * Set the virtioInterface property: Field Deprecated, use virtualizationModel instead. The type of the virtio
     * interface.
     *
     * @param virtioInterface the virtioInterface value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withVirtioInterface(VirtualMachineVirtioInterfaceType virtioInterface) {
        this.virtioInterface = virtioInterface;
        return this;
    }

    /**
     * Get the vmDeviceModel property: The type of the device model to use.
     *
     * @return the vmDeviceModel value.
     */
    public VirtualMachineDeviceModelType vmDeviceModel() {
        return this.vmDeviceModel;
    }

    /**
     * Set the vmDeviceModel property: The type of the device model to use.
     *
     * @param vmDeviceModel the vmDeviceModel value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withVmDeviceModel(VirtualMachineDeviceModelType vmDeviceModel) {
        this.vmDeviceModel = vmDeviceModel;
        return this;
    }

    /**
     * Get the vmImage property: The virtual machine image that is currently provisioned to the OS disk, using the full
     * url and tag notation used to pull the image.
     *
     * @return the vmImage value.
     */
    public String vmImage() {
        return this.vmImage;
    }

    /**
     * Set the vmImage property: The virtual machine image that is currently provisioned to the OS disk, using the full
     * url and tag notation used to pull the image.
     *
     * @param vmImage the vmImage value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withVmImage(String vmImage) {
        this.vmImage = vmImage;
        return this;
    }

    /**
     * Get the vmImageRepositoryCredentials property: ImageRepositoryCredentials represents the credentials used to
     * login to the image repository.
     *
     * <p>The credentials used to login to the image repository that has access to the specified image.
     *
     * @return the vmImageRepositoryCredentials value.
     */
    public ImageRepositoryCredentials vmImageRepositoryCredentials() {
        return this.vmImageRepositoryCredentials;
    }

    /**
     * Set the vmImageRepositoryCredentials property: ImageRepositoryCredentials represents the credentials used to
     * login to the image repository.
     *
     * <p>The credentials used to login to the image repository that has access to the specified image.
     *
     * @param vmImageRepositoryCredentials the vmImageRepositoryCredentials value to set.
     * @return the VirtualMachineProperties object itself.
     */
    public VirtualMachineProperties withVmImageRepositoryCredentials(
        ImageRepositoryCredentials vmImageRepositoryCredentials) {
        this.vmImageRepositoryCredentials = vmImageRepositoryCredentials;
        return this;
    }

    /**
     * Get the volumes property: The resource IDs of volumes that are attached to the virtual machine.
     *
     * @return the volumes value.
     */
    public List<String> volumes() {
        return this.volumes;
    }

    /**
     * Validates the instance.
     *
     * @throws IllegalArgumentException thrown if the instance is not valid.
     */
    public void validate() {
        if (adminUsername() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property adminUsername in model VirtualMachineProperties"));
        }
        if (cloudServicesNetworkAttachment() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property cloudServicesNetworkAttachment in model VirtualMachineProperties"));
        } else {
            cloudServicesNetworkAttachment().validate();
        }
        if (networkAttachments() != null) {
            networkAttachments().forEach(e -> e.validate());
        }
        if (placementHints() != null) {
            placementHints().forEach(e -> e.validate());
        }
        if (sshPublicKeys() != null) {
            sshPublicKeys().forEach(e -> e.validate());
        }
        if (storageProfile() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property storageProfile in model VirtualMachineProperties"));
        } else {
            storageProfile().validate();
        }
        if (vmImage() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property vmImage in model VirtualMachineProperties"));
        }
        if (vmImageRepositoryCredentials() != null) {
            vmImageRepositoryCredentials().validate();
        }
    }

    private static final ClientLogger LOGGER = new ClientLogger(VirtualMachineProperties.class);
}
