data "vsphere_datacenter" "dc" {
  name = var.vsphere_datacenter_name
}

data "vsphere_datastore" "datastore" {
  name          = var.vsphere_datastore_name
  datacenter_id = data.vsphere_datacenter.dc.id
}

data "vsphere_compute_cluster" "cluster" {
  count         = var.vsphere_host == "" ? 1 : 0
  name          = var.vsphere_compute_cluster_name
  datacenter_id = data.vsphere_datacenter.dc.id
}

data "vsphere_host" "host" {
  count         = var.vsphere_host != "" ? 1 : 0
  name          = var.vsphere_host
  datacenter_id = data.vsphere_datacenter.dc.id
}

data "vsphere_network" "network" {
  name          = var.vsphere_network_name
  datacenter_id = data.vsphere_datacenter.dc.id
}

data "vsphere_virtual_machine" "vm_template" {
  name          = var.vm_template_name
  datacenter_id = data.vsphere_datacenter.dc.id
}

resource "vsphere_virtual_machine" "virtual_machine" {
  for_each                     = toset(var.vm_hostnames)
  name                         = each.value
  resource_pool_id             = var.vsphere_host != "" ? data.vsphere_host.host[0].resource_pool_id : data.vsphere_compute_cluster.cluster[0].resource_pool_id
  datastore_id                 = data.vsphere_datastore.datastore.id
  num_cpus                     = var.vm_num_cpus
  num_cores_per_socket         = var.vm_num_cores_per_socket
  memory                       = var.vm_memory
  guest_id                     = data.vsphere_virtual_machine.vm_template.guest_id
  scsi_type                    = data.vsphere_virtual_machine.vm_template.scsi_type
  enable_disk_uuid             = var.enable_disk_uuid
  extra_config_reboot_required = false

  dynamic "network_interface" {
    for_each = local.combined_network_interfaces
    content {
      network_id   = network_interface.value.id
      adapter_type = network_interface.value.adapter_type
    }
  }

  disk {
    label            = "disk0"
    size             = data.vsphere_virtual_machine.vm_template.disks[0].size
    eagerly_scrub    = data.vsphere_virtual_machine.vm_template.disks[0].eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.vm_template.disks[0].thin_provisioned
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.vm_template.id

    customize {
      linux_options {
        host_name = each.value
        domain    = var.vm_domain
      }

      # This sets to DHCP
      dynamic network_interface {
        for_each = local.combined_network_interfaces
        content {}
      }
    }
  }

  # Allow external changes without Terraform caring
  lifecycle {
    ignore_changes = [
      boot_delay,
      boot_retry_enabled,
      clone,
      cpu_hot_add_enabled,
      cpu_hot_remove_enabled,
      cpu_limit,
      cpu_performance_counters_enabled,
      cpu_reservation,
      custom_attributes,
      datastore_id,
      disk,
      efi_secure_boot_enabled,
      enable_disk_uuid,
      enable_logging,
      ept_rvi_mode,
      extra_config,
      guest_id,
      guest_ip_addresses,
      hv_mode,
      memory_hot_add_enabled,
      memory_reservation,
      nested_hv_enabled,
      network_interface,
      resource_pool_id,
      run_tools_scripts_before_guest_reboot,
      sync_time_with_host,
      tags,
      uuid,
      vapp_transport,
      vmware_tools_status,
      vmx_path,
    ]
  }

  provisioner "remote-exec" {
    inline = var.vm_update_commands

    connection {
      type        = "ssh"
      user        = var.ssh_user
      private_key = local.ssh_private_key
      host        = self.default_ip_address
    }
  }

  provisioner "remote-exec" {
    inline = var.vm_custom_post_boot_commands

    connection {
      type        = "ssh"
      user        = var.ssh_user
      private_key = local.ssh_private_key
      host        = self.default_ip_address
    }
  }

  provisioner "local-exec" {
    command = "${var.chef_bootstrap_script_path} -c ${var.chef_client_version} -h ${each.value} -u ${var.ssh_user} -k ${var.ssh_private_key_path} -i ${self.default_ip_address} ${var.chef_bootstrap_script_additional_args}"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo reboot &",
    ]

    connection {
      type        = "ssh"
      user        = var.ssh_user
      private_key = local.ssh_private_key
      host        = self.default_ip_address
    }
  }

  provisioner "local-exec" {
    when    = destroy
    command = "knife node delete -y ${each.key}; knife client delete -y ${each.key}"
  }
}

locals {
  combined_network_interfaces = concat([
    {
      id           = data.vsphere_network.network.id
      adapter_type = data.vsphere_virtual_machine.vm_template.network_interface_types[0]
    }
  ], var.extra_network_interfaces)
}
