//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

package cloudstack

import (
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"log"
	"strings"

	"github.com/apache/cloudstack-go/v2/cloudstack"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceCloudStackInstance() *schema.Resource {
	return &schema.Resource{
		Create: resourceCloudStackInstanceCreate,
		Read:   resourceCloudStackInstanceRead,
		Update: resourceCloudStackInstanceUpdate,
		Delete: resourceCloudStackInstanceDelete,
		Importer: &schema.ResourceImporter{
			State: resourceCloudStackInstanceImport,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"display_name": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"service_offering": {
				Type:     schema.TypeString,
				Required: true,
			},

			"disk_offering": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"override_disk_offering": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"network_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"ip_address": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"template": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"root_disk_size": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"group": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"affinity_group_ids": {
				Type:          schema.TypeSet,
				Optional:      true,
				Elem:          &schema.Schema{Type: schema.TypeString},
				Set:           schema.HashString,
				ConflictsWith: []string{"affinity_group_names"},
			},

			"affinity_group_names": {
				Type:          schema.TypeSet,
				Optional:      true,
				Elem:          &schema.Schema{Type: schema.TypeString},
				Set:           schema.HashString,
				ConflictsWith: []string{"affinity_group_ids"},
			},

			"security_group_ids": {
				Type:          schema.TypeSet,
				Optional:      true,
				ForceNew:      true,
				Elem:          &schema.Schema{Type: schema.TypeString},
				Set:           schema.HashString,
				ConflictsWith: []string{"security_group_names"},
			},

			"security_group_names": {
				Type:          schema.TypeSet,
				Optional:      true,
				ForceNew:      true,
				Elem:          &schema.Schema{Type: schema.TypeString},
				Set:           schema.HashString,
				ConflictsWith: []string{"security_group_ids"},
			},

			"project": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"zone": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"keypair": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"keypairs"},
			},

			"keypairs": {
				Type:          schema.TypeList,
				Optional:      true,
				Elem:          &schema.Schema{Type: schema.TypeString},
				ConflictsWith: []string{"keypair"},
			},

			"host_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"cluster_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"uefi": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"boot_mode": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringInSlice([]string{"Secure", "Legacy"}, true),
				ForceNew:     true,
				Description:  "The boot mode of the instance. Can only be specified when uefi is true. Valid options are 'Legacy' and 'Secure'.",
			},

			"start_vm": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  true,
				ForceNew: true,
			},

			"user_data": {
				Type:     schema.TypeString,
				Optional: true,
				StateFunc: func(v interface{}) string {
					switch v.(type) {
					case string:
						hash := sha1.Sum([]byte(v.(string)))
						return hex.EncodeToString(hash[:])
					default:
						return ""
					}
				},
			},

			"userdata_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"userdata_details": {
				Type:     schema.TypeMap,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
			},

			"details": {
				Type:     schema.TypeMap,
				Optional: true,
			},

			"properties": {
				Type:     schema.TypeMap,
				Optional: true,
			},

			"nicnetworklist": {
				Type:     schema.TypeMap,
				Optional: true,
			},

			"expunge": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"pod_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"delete_protection": {
				Type:     schema.TypeBool,
				Optional: true,
				Computed: true,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{}) error {

	cs := meta.(*cloudstack.CloudStackClient)

	// Retrieve the zone ID first (needed for service_offering lookup)
	zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
	if e != nil {
		return e.Error()
	}

	// Retrieve the service_offering ID (filtered by zone)
	serviceofferingid, e := retrieveServiceOfferingID(cs, zoneid, d.Get("service_offering").(string))
	if e != nil {
		return e.Error()
	}

	// Retrieve the zone object
	zone, _, err := cs.Zone.GetZoneByID(zoneid)
	if err != nil {
		return err
	}

	// Retrieve the template ID
	templateid, e := retrieveTemplateID(cs, zone.Id, d.Get("template").(string))
	if e != nil {
		return e.Error()
	}

	if bootMode, hasBoot := d.GetOk("boot_mode"); hasBoot && !d.Get("uefi").(bool) {
		return fmt.Errorf("boot_mode can only be specified when uefi is true, got boot_mode=%s with uefi=false", bootMode.(string))
	}

	// Create a new parameter struct
	p := cs.VirtualMachine.NewDeployVirtualMachineParams(serviceofferingid, templateid, zone.Id)
	p.SetStartvm(d.Get("start_vm").(bool))
	vmDetails := make(map[string]string)
	if details, ok := d.GetOk("details"); ok {
		for k, v := range details.(map[string]interface{}) {
			vmDetails[k] = v.(string)
		}
		p.SetDetails(vmDetails)
	}

	// Set VM Properties
	vmProperties := make(map[string]string)
	if properties, ok := d.GetOk("properties"); ok {
		for k, v := range properties.(map[string]interface{}) {
			vmProperties[k] = v.(string)
		}
		p.SetProperties(vmProperties)
	}

	// SetNicNetworkList
	if nicnetworklist, ok := d.GetOk("nicnetworklist"); ok {
		nicNetworkDetails := []map[string]string{
			{
				"nic":     nicnetworklist.(map[string]interface{})["nic"].(string),
				"network": nicnetworklist.(map[string]interface{})["network"].(string),
			},
		}
		p.SetNicnetworklist(nicNetworkDetails)
	}

	// Set the name
	name, hasName := d.GetOk("name")
	if hasName {
		p.SetName(name.(string))
	}

	// Set the display name
	if displayname, ok := d.GetOk("display_name"); ok {
		p.SetDisplayname(displayname.(string))
	} else if hasName {
		p.SetDisplayname(name.(string))
	}

	// If there is a root_disk_size supplied, add it to the parameter struct
	if rootdisksize, ok := d.GetOk("root_disk_size"); ok {
		p.SetRootdisksize(int64(rootdisksize.(int)))
	}

	if diskoffering, ok := d.GetOk("disk_offering"); ok {
		// Retrieve the disk_offering ID
		diskofferingid, e := retrieveID(cs, "disk_offering", diskoffering.(string))
		if e != nil {
			return e.Error()
		}
		p.SetDiskofferingid(diskofferingid)
	}

	if override_disk_offering, ok := d.GetOk("override_disk_offering"); ok {
		// Retrieve the override_disk_offering ID
		override_disk_offeringid, e := retrieveID(cs, "disk_offering", override_disk_offering.(string))
		if e != nil {
			return e.Error()
		}
		p.SetOverridediskofferingid(override_disk_offeringid)
	}

	if d.Get("uefi").(bool) {
		p.SetBoottype("UEFI")
		if bootmode, ok := d.GetOk("boot_mode"); ok {
			p.SetBootmode(bootmode.(string))
		} else {
			p.SetBootmode("Legacy")
		}
	}

	if zone.Networktype == "Advanced" {
		// Set the default network ID
		networkID := d.Get("network_id").(string)
		p.SetNetworkids([]string{networkID})

		// If no project is explicitly set, try to inherit it from the network
		if _, ok := d.GetOk("project"); !ok && networkID != "" {
			// Get the network to retrieve its project
			// Use projectid=-1 to search across all projects
			network, count, err := cs.Network.GetNetworkByID(networkID, cloudstack.WithProject("-1"))
			if err == nil && count > 0 && network.Projectid != "" {
				log.Printf("[DEBUG] Inheriting project %s from network %s", network.Projectid, networkID)
				p.SetProjectid(network.Projectid)
			}
		}
	}

	// If there is a ipaddres supplied, add it to the parameter struct
	if ipaddress, ok := d.GetOk("ip_address"); ok {
		p.SetIpaddress(ipaddress.(string))
	}

	// If there is a group supplied, add it to the parameter struct
	if group, ok := d.GetOk("group"); ok {
		p.SetGroup(group.(string))
	}

	// If there are affinity group IDs supplied, add them to the parameter struct
	if agIDs := d.Get("affinity_group_ids").(*schema.Set); agIDs.Len() > 0 {
		var groups []string
		for _, group := range agIDs.List() {
			groups = append(groups, group.(string))
		}
		p.SetAffinitygroupids(groups)
	}

	// If there are affinity group names supplied, add them to the parameter struct
	if agNames := d.Get("affinity_group_names").(*schema.Set); agNames.Len() > 0 {
		var groups []string
		for _, group := range agNames.List() {
			groups = append(groups, group.(string))
		}
		p.SetAffinitygroupnames(groups)
	}

	// If there are security group IDs supplied, add them to the parameter struct
	if sgIDs := d.Get("security_group_ids").(*schema.Set); sgIDs.Len() > 0 {
		var groups []string
		for _, group := range sgIDs.List() {
			groups = append(groups, group.(string))
		}
		p.SetSecuritygroupids(groups)
	}

	// If there are security group names supplied, add them to the parameter struct
	if sgNames := d.Get("security_group_names").(*schema.Set); sgNames.Len() > 0 {
		var groups []string
		for _, group := range sgNames.List() {
			groups = append(groups, group.(string))
		}
		p.SetSecuritygroupnames(groups)
	}

	// If there is a project supplied, we retrieve and set the project id
	// This will override the inherited project from network if explicitly set
	if err := setProjectid(p, cs, d); err != nil {
		return err
	}

	// If a keypair is supplied, add it to the parameter struct
	if keypair, ok := d.GetOk("keypair"); ok {
		p.SetKeypair(keypair.(string))
	}

	if keypairs, ok := d.GetOk("keypairs"); ok {
		var keypairStrings []string
		for _, kp := range keypairs.([]interface{}) {
			keypairStrings = append(keypairStrings, fmt.Sprintf("%v", kp))
		}
		p.SetKeypairs(keypairStrings)
	}

	// If a host_id is supplied, add it to the parameter struct

	if hostid, ok := d.GetOk("host_id"); ok {
		p.SetHostid(hostid.(string))
	}

	// If a pod_id is supplied, add it to the parameter struct

	if podid, ok := d.GetOk("pod_id"); ok {
		p.SetPodid(podid.(string))
	}

	// If a cluster_id is supplied, add it to the parameter struct

	if clusterid, ok := d.GetOk("cluster_id"); ok {
		p.SetClusterid(clusterid.(string))
	}

	if userData, ok := d.GetOk("user_data"); ok {
		ud, err := getUserData(userData.(string))
		if err != nil {
			return err
		}
		p.SetUserdata(ud)
	}

	if userdataID, ok := d.GetOk("userdata_id"); ok {
		p.SetUserdataid(userdataID.(string))
	}

	if userdataDetails, ok := d.GetOk("userdata_details"); ok {
		ud := make(map[string]string)
		for k, v := range userdataDetails.(map[string]interface{}) {
			ud[k] = v.(string)
		}
		p.SetUserdatadetails(ud)
	}

	// Create the new instance
	r, err := cs.VirtualMachine.DeployVirtualMachine(p)
	if err != nil {
		return fmt.Errorf("Error creating the new instance %s: %s", name, err)
	}

	d.SetId(r.Id)

	// Set delete protection using UpdateVirtualMachine
	if v, ok := d.GetOk("delete_protection"); ok {
		p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
		p.SetDeleteprotection(v.(bool))

		_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating the delete protection for instance %s: %s", name, err)
		}
	}

	// Set tags if necessary
	if err = setTags(cs, d, "userVm"); err != nil {
		return fmt.Errorf("Error setting tags on the new instance %s: %s", name, err)
	}

	// Set the connection info for any configured provisioners
	d.SetConnInfo(map[string]string{
		"host":     r.Nic[0].Ipaddress,
		"password": r.Password,
	})

	return resourceCloudStackInstanceRead(d, meta)
}

func resourceCloudStackInstanceRead(d *schema.ResourceData, meta interface{}) error {
	cs := meta.(*cloudstack.CloudStackClient)

	// Get the virtual machine details
	// First try with the project from state (if any)
	project := d.Get("project").(string)
	vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(
		d.Id(),
		cloudstack.WithProject(project),
	)

	// If not found and no explicit project was set, try with projectid=-1
	// This handles the case where the project was inherited from network
	if count == 0 && project == "" {
		vm, count, err = cs.VirtualMachine.GetVirtualMachineByID(
			d.Id(),
			cloudstack.WithProject("-1"),
		)
	}

	if err != nil {
		if count == 0 {
			log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("name").(string))
			d.SetId("")
			return nil
		}

		return err
	}

	// Update the config
	d.Set("name", vm.Name)
	d.Set("display_name", vm.Displayname)
	d.Set("group", vm.Group)
	d.Set("delete_protection", vm.Deleteprotection)

	// In some rare cases (when destroying a machine fails) it can happen that
	// an instance does not have any attached NIC anymore.
	if len(vm.Nic) > 0 {
		d.Set("network_id", vm.Nic[0].Networkid)
		d.Set("ip_address", vm.Nic[0].Ipaddress)
	}

	// Create a new param struct.
	p := cs.Volume.NewListVolumesParams()
	p.SetType("ROOT")
	p.SetVirtualmachineid(d.Id())

	// Get the root disk of the instance.
	l, err := cs.Volume.ListVolumes(p)
	if err != nil {
		return err
	}

	// If we found the root disk, then update its size.
	if len(l.Volumes) != 1 {
		log.Printf("[DEBUG] Failed to find root disk of instance: %s", vm.Name)
	} else {
		d.Set("root_disk_size", l.Volumes[0].Size>>30) // B to GiB
	}

	if _, ok := d.GetOk("affinity_group_ids"); ok {
		groups := &schema.Set{F: schema.HashString}
		for _, group := range vm.Affinitygroup {
			groups.Add(group.Id)
		}
		d.Set("affinity_group_ids", groups)
	}

	if _, ok := d.GetOk("affinity_group_names"); ok {
		groups := &schema.Set{F: schema.HashString}
		for _, group := range vm.Affinitygroup {
			groups.Add(group.Name)
		}
		d.Set("affinity_group_names", groups)
	}

	if _, ok := d.GetOk("security_group_ids"); ok {
		groups := &schema.Set{F: schema.HashString}
		for _, group := range vm.Securitygroup {
			groups.Add(group.Id)
		}
		d.Set("security_group_ids", groups)
	}

	if _, ok := d.GetOk("security_group_names"); ok {
		groups := &schema.Set{F: schema.HashString}
		for _, group := range vm.Securitygroup {
			groups.Add(group.Name)
		}
		d.Set("security_group_names", groups)
	}

	d.Set("tags", tagsToMap(vm.Tags))

	setValueOrID(d, "service_offering", vm.Serviceofferingname, vm.Serviceofferingid)
	setValueOrID(d, "disk_offering", vm.Diskofferingname, vm.Diskofferingid)
	setValueOrID(d, "template", vm.Templatename, vm.Templateid)
	setValueOrID(d, "project", vm.Project, vm.Projectid)
	setValueOrID(d, "zone", vm.Zonename, vm.Zoneid)
	d.Set("uefi", strings.EqualFold(vm.Boottype, "UEFI"))
	if strings.EqualFold(vm.Boottype, "UEFI") && vm.Bootmode != "" {
		d.Set("boot_mode", vm.Bootmode)
	}

	if vm.Userdataid != "" {
		d.Set("userdata_id", vm.Userdataid)
	}

	if vm.Userdata != "" {
		decoded, err := base64.StdEncoding.DecodeString(vm.Userdata)
		if err != nil {
			d.Set("user_data", vm.Userdata)
		} else {
			d.Set("user_data", string(decoded))
		}
	}

	if vm.Userdatadetails != "" {
		log.Printf("[DEBUG] Instance %s has userdata details: %s", vm.Name, vm.Userdatadetails)
	}

	return nil
}

func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) error {

	cs := meta.(*cloudstack.CloudStackClient)

	name := d.Get("name").(string)

	// Check if the display name is changed and if so, update the virtual machine
	if d.HasChange("display_name") {
		log.Printf("[DEBUG] Display name changed for %s, starting update", name)

		// Create a new parameter struct
		p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())

		// Set the new display name
		p.SetDisplayname(d.Get("display_name").(string))

		// Update the display name
		_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating the display name for instance %s: %s", name, err)
		}

	}

	// Check if the group is changed and if so, update the virtual machine
	if d.HasChange("group") {
		log.Printf("[DEBUG] Group changed for %s, starting update", name)

		// Create a new parameter struct
		p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())

		// Set the new group
		p.SetGroup(d.Get("group").(string))

		// Update the display name
		_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating the group for instance %s: %s", name, err)
		}

	}

	// Attributes that require reboot to update
	if d.HasChange("name") || d.HasChange("service_offering") || d.HasChange("affinity_group_ids") ||
		d.HasChange("affinity_group_names") || d.HasChange("keypair") || d.HasChange("keypairs") ||
		d.HasChange("user_data") || d.HasChange("userdata_id") || d.HasChange("userdata_details") {

		// Before we can actually make these changes, the virtual machine must be stopped
		_, err := cs.VirtualMachine.StopVirtualMachine(
			cs.VirtualMachine.NewStopVirtualMachineParams(d.Id()))
		if err != nil {
			return fmt.Errorf(
				"Error stopping instance %s before making changes: %s", name, err)
		}

		// Check if the name has changed and if so, update the name
		if d.HasChange("name") {
			log.Printf("[DEBUG] Name for %s changed to %s, starting update", d.Id(), name)

			// Create a new parameter struct
			p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())

			// Set the new name
			p.SetName(name)

			// Update the display name
			_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating the name for instance %s: %s", name, err)
			}

		}

		// Check if the service offering is changed and if so, update the offering
		if d.HasChange("service_offering") {
			log.Printf("[DEBUG] Service offering changed for %s, starting update", name)

			// Retrieve the zone ID first (needed for service_offering lookup)
			zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
			if e != nil {
				return e.Error()
			}

			// Retrieve the service_offering ID (filtered by zone)
			serviceofferingid, e := retrieveServiceOfferingID(cs, zoneid, d.Get("service_offering").(string))
			if e != nil {
				return e.Error()
			}

			// Create a new parameter struct
			p := cs.VirtualMachine.NewChangeServiceForVirtualMachineParams(d.Id(), serviceofferingid)

			// Change the service offering
			_, err = cs.VirtualMachine.ChangeServiceForVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error changing the service offering for instance %s: %s", name, err)
			}
		}

		// Check if the affinity group IDs have changed and if so, update the IDs
		if d.HasChange("affinity_group_ids") {
			p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
			groups := []string{}

			if agIDs := d.Get("affinity_group_ids").(*schema.Set); agIDs.Len() > 0 {
				for _, group := range agIDs.List() {
					groups = append(groups, group.(string))
				}
			}

			// Set the new groups
			p.SetAffinitygroupids(groups)

			// Update the affinity groups
			_, err = cs.AffinityGroup.UpdateVMAffinityGroup(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating the affinity groups for instance %s: %s", name, err)
			}
		}

		// Check if the affinity group names have changed and if so, update the names
		if d.HasChange("affinity_group_names") {
			p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
			groups := []string{}

			if agNames := d.Get("affinity_group_names").(*schema.Set); agNames.Len() > 0 {
				for _, group := range agNames.List() {
					groups = append(groups, group.(string))
				}
			}

			// Set the new groups
			p.SetAffinitygroupnames(groups)

			// Update the affinity groups
			_, err = cs.AffinityGroup.UpdateVMAffinityGroup(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating the affinity groups for instance %s: %s", name, err)
			}
		}

		// Check if the keypair has changed and if so, update the keypair
		if d.HasChange("keypair") || d.HasChange("keypairs") {
			log.Printf("[DEBUG] SSH keypair(s) changed for %s, starting update", name)

			p := cs.SSH.NewResetSSHKeyForVirtualMachineParams(d.Id())

			if keypair, ok := d.GetOk("keypair"); ok {
				p.SetKeypair(keypair.(string))
			}

			if keypairs, ok := d.GetOk("keypairs"); ok {

				// Convert keypairsInterface to []interface{}
				keypairsInterfaces := keypairs.([]interface{})

				// Now, safely convert []interface{} to []string with error handling
				strKeyPairs := make([]string, len(keypairsInterfaces))

				for i, v := range keypairsInterfaces {
					switch v := v.(type) {
					case string:
						strKeyPairs[i] = v
					default:
						log.Printf("Value at index %d is not a string: %v", i, v)
						continue
					}
				}
				p.SetKeypairs(strKeyPairs)
			}

			// If there is a project supplied, we retrieve and set the project id
			if err := setProjectid(p, cs, d); err != nil {
				return err
			}
			// Change the ssh keypair
			_, err = cs.SSH.ResetSSHKeyForVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error changing the SSH keypair(s) for instance %s: %s", name, err)
			}
		}

		// Check if the user data has changed and if so, update the user data
		if d.HasChange("user_data") {
			log.Printf("[DEBUG] user_data changed for %s, starting update", name)

			ud, err := getUserData(d.Get("user_data").(string))
			if err != nil {
				return err
			}

			p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
			p.SetUserdata(ud)
			_, err = cs.VirtualMachine.UpdateVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating user_data for instance %s: %s", name, err)
			}
		}

		if d.HasChange("userdata_id") {
			log.Printf("[DEBUG] userdata_id changed for %s, starting update", name)

			p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
			if userdataID, ok := d.GetOk("userdata_id"); ok {
				p.SetUserdataid(userdataID.(string))
			}
			_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating userdata_id for instance %s: %s", name, err)
			}
		}

		if d.HasChange("userdata_details") {
			log.Printf("[DEBUG] userdata_details changed for %s, starting update", name)

			p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
			if userdataDetails, ok := d.GetOk("userdata_details"); ok {
				ud := make(map[string]string)
				for k, v := range userdataDetails.(map[string]interface{}) {
					ud[k] = v.(string)
				}
				p.SetUserdatadetails(ud)
			}
			_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
			if err != nil {
				return fmt.Errorf(
					"Error updating userdata_details for instance %s: %s", name, err)
			}
		}

		// Start the virtual machine again
		_, err = cs.VirtualMachine.StartVirtualMachine(
			cs.VirtualMachine.NewStartVirtualMachineParams(d.Id()))
		if err != nil {
			return fmt.Errorf(
				"Error starting instance %s after making changes", name)
		}
	}

	// Check if the tags have changed and if so, update the tags
	if d.HasChange("tags") {
		if err := updateTags(cs, d, "UserVm"); err != nil {
			return fmt.Errorf("Error updating tags on instance %s: %s", name, err)
		}
	}

	// Check if the details have changed and if so, update the details
	if d.HasChange("details") {
		p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
		vmDetails := make(map[string]string)
		if details := d.Get("details"); details != nil {
			for k, v := range details.(map[string]interface{}) {
				vmDetails[k] = v.(string)
			}
		}
		p.SetDetails(vmDetails)
		_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating the details for instance %s: %s", vmDetails, err)
		}
	}

	// Check if the delete protection has changed and if so, update the deleteprotection
	if d.HasChange("delete_protection") {
		p := cs.VirtualMachine.NewUpdateVirtualMachineParams(d.Id())
		p.SetDeleteprotection(d.Get("delete_protection").(bool))

		_, err := cs.VirtualMachine.UpdateVirtualMachine(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating the delete protection for instance %s: %s", name, err)
		}
	}

	return resourceCloudStackInstanceRead(d, meta)
}

func resourceCloudStackInstanceDelete(d *schema.ResourceData, meta interface{}) error {
	cs := meta.(*cloudstack.CloudStackClient)

	// Create a new parameter struct
	p := cs.VirtualMachine.NewDestroyVirtualMachineParams(d.Id())

	if d.Get("expunge").(bool) {
		p.SetExpunge(true)
	}

	log.Printf("[INFO] Destroying instance: %s", d.Get("name").(string))
	if _, err := cs.VirtualMachine.DestroyVirtualMachine(p); err != nil {
		// This is a very poor way to be told the ID does no longer exist :(
		if strings.Contains(err.Error(), fmt.Sprintf(
			"Invalid parameter id value=%s due to incorrect long value format, "+
				"or entity does not exist", d.Id())) {
			return nil
		}

		return fmt.Errorf("Error destroying instance: %s", err)
	}

	return nil
}
func resourceCloudStackInstanceImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	// We set start_vm to true as that matches the default and we assume that
	// when you need to import an instance it means it is already running.
	d.Set("start_vm", true)
	return importStatePassthrough(d, meta)
}

// getUserData returns the user data as a base64 encoded string
func getUserData(userData string) (string, error) {
	ud := userData
	if _, err := base64.StdEncoding.DecodeString(ud); err != nil {
		ud = base64.StdEncoding.EncodeToString([]byte(userData))
	}

	return ud, nil
}
