// 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.management.Resource;
import com.azure.core.management.SystemData;
import com.azure.core.util.logging.ClientLogger;
import com.azure.resourcemanager.networkcloud.models.ExtendedLocation;
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;
import java.util.Map;

/** VirtualMachine represents the on-premises Network Cloud virtual machine. */
@Fluent
public final class VirtualMachineInner extends Resource {
    /*
     * ExtendedLocation represents the Azure custom location where the resource will be created.
     *
     * The extended location of the cluster associated with the resource.
     */
    @JsonProperty(value = "extendedLocation", required = true)
    private ExtendedLocation extendedLocation;

    /*
     * VirtualMachineProperties represents the properties of the virtual machine.
     *
     * The list of the resource properties.
     */
    @JsonProperty(value = "properties", required = true)
    private VirtualMachineProperties innerProperties = new VirtualMachineProperties();

    /*
     * Azure Resource Manager metadata containing createdBy and modifiedBy information.
     */
    @JsonProperty(value = "systemData", access = JsonProperty.Access.WRITE_ONLY)
    private SystemData systemData;

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

    /**
     * Get the extendedLocation property: ExtendedLocation represents the Azure custom location where the resource will
     * be created.
     *
     * <p>The extended location of the cluster associated with the resource.
     *
     * @return the extendedLocation value.
     */
    public ExtendedLocation extendedLocation() {
        return this.extendedLocation;
    }

    /**
     * Set the extendedLocation property: ExtendedLocation represents the Azure custom location where the resource will
     * be created.
     *
     * <p>The extended location of the cluster associated with the resource.
     *
     * @param extendedLocation the extendedLocation value to set.
     * @return the VirtualMachineInner object itself.
     */
    public VirtualMachineInner withExtendedLocation(ExtendedLocation extendedLocation) {
        this.extendedLocation = extendedLocation;
        return this;
    }

    /**
     * Get the innerProperties property: VirtualMachineProperties represents the properties of the virtual machine.
     *
     * <p>The list of the resource properties.
     *
     * @return the innerProperties value.
     */
    private VirtualMachineProperties innerProperties() {
        return this.innerProperties;
    }

    /**
     * Get the systemData property: Azure Resource Manager metadata containing createdBy and modifiedBy information.
     *
     * @return the systemData value.
     */
    public SystemData systemData() {
        return this.systemData;
    }

    /** {@inheritDoc} */
    @Override
    public VirtualMachineInner withLocation(String location) {
        super.withLocation(location);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public VirtualMachineInner withTags(Map<String, String> tags) {
        super.withTags(tags);
        return this;
    }

    /**
     * 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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withAdminUsername(String adminUsername) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withAdminUsername(adminUsername);
        return this;
    }

    /**
     * Get the availabilityZone property: The cluster availability zone containing this virtual machine.
     *
     * @return the availabilityZone value.
     */
    public String availabilityZone() {
        return this.innerProperties() == null ? null : this.innerProperties().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.innerProperties() == null ? null : this.innerProperties().bareMetalMachineId();
    }

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

    /**
     * Set the bootMethod property: Selects the boot method for the virtual machine.
     *
     * @param bootMethod the bootMethod value to set.
     * @return the VirtualMachineInner object itself.
     */
    public VirtualMachineInner withBootMethod(VirtualMachineBootMethod bootMethod) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withBootMethod(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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withCloudServicesNetworkAttachment(NetworkAttachment cloudServicesNetworkAttachment) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withCloudServicesNetworkAttachment(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.innerProperties() == null ? null : this.innerProperties().clusterId();
    }

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

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

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

    /**
     * Get the detailedStatusMessage property: The descriptive message about the current detailed status.
     *
     * @return the detailedStatusMessage value.
     */
    public String detailedStatusMessage() {
        return this.innerProperties() == null ? null : this.innerProperties().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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withIsolateEmulatorThread(VirtualMachineIsolateEmulatorThread isolateEmulatorThread) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withIsolateEmulatorThread(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.innerProperties() == null ? 0L : this.innerProperties().memorySizeGB();
    }

    /**
     * Set the memorySizeGB property: The memory size of the virtual machine in GB.
     *
     * @param memorySizeGB the memorySizeGB value to set.
     * @return the VirtualMachineInner object itself.
     */
    public VirtualMachineInner withMemorySizeGB(long memorySizeGB) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withMemorySizeGB(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.innerProperties() == null ? null : this.innerProperties().networkAttachments();
    }

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

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

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

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

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

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

    /**
     * Get the provisioningState property: The provisioning state of the virtual machine.
     *
     * @return the provisioningState value.
     */
    public VirtualMachineProvisioningState provisioningState() {
        return this.innerProperties() == null ? null : this.innerProperties().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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withSshPublicKeys(List<SshPublicKey> sshPublicKeys) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withSshPublicKeys(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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withStorageProfile(StorageProfile storageProfile) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withStorageProfile(storageProfile);
        return this;
    }

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

    /**
     * Set the userData property: The Base64 encoded cloud-init user data.
     *
     * @param userData the userData value to set.
     * @return the VirtualMachineInner object itself.
     */
    public VirtualMachineInner withUserData(String userData) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withUserData(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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withVirtioInterface(VirtualMachineVirtioInterfaceType virtioInterface) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withVirtioInterface(virtioInterface);
        return this;
    }

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

    /**
     * Set the vmDeviceModel property: The type of the device model to use.
     *
     * @param vmDeviceModel the vmDeviceModel value to set.
     * @return the VirtualMachineInner object itself.
     */
    public VirtualMachineInner withVmDeviceModel(VirtualMachineDeviceModelType vmDeviceModel) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withVmDeviceModel(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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withVmImage(String vmImage) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withVmImage(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.innerProperties() == null ? null : this.innerProperties().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 VirtualMachineInner object itself.
     */
    public VirtualMachineInner withVmImageRepositoryCredentials(
        ImageRepositoryCredentials vmImageRepositoryCredentials) {
        if (this.innerProperties() == null) {
            this.innerProperties = new VirtualMachineProperties();
        }
        this.innerProperties().withVmImageRepositoryCredentials(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.innerProperties() == null ? null : this.innerProperties().volumes();
    }

    /**
     * Validates the instance.
     *
     * @throws IllegalArgumentException thrown if the instance is not valid.
     */
    public void validate() {
        if (extendedLocation() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property extendedLocation in model VirtualMachineInner"));
        } else {
            extendedLocation().validate();
        }
        if (innerProperties() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property innerProperties in model VirtualMachineInner"));
        } else {
            innerProperties().validate();
        }
    }

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