//
// 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 (
	"fmt"
	"log"
	"strings"
	"time"

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

func resourceCloudStackTemplate() *schema.Resource {
	return &schema.Resource{
		Create: resourceCloudStackTemplateCreate,
		Read:   resourceCloudStackTemplateRead,
		Update: resourceCloudStackTemplateUpdate,
		Delete: resourceCloudStackTemplateDelete,

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

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

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

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

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

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

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

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

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

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

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

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

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

			"is_ready": {
				Type:     schema.TypeBool,
				Computed: true,
			},

			"is_ready_timeout": {
				Type:     schema.TypeInt,
				Optional: true,
				Default:  300,
			},

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

			"userdata_link": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"userdata_id": {
							Type:        schema.TypeString,
							Required:    true,
							Description: "The ID of the user data to link to the template.",
						},
						"userdata_policy": {
							Type:        schema.TypeString,
							Optional:    true,
							Default:     "ALLOWOVERRIDE",
							Description: "Override policy of the userdata. Possible values: ALLOWOVERRIDE, APPEND, DENYOVERRIDE. Default: ALLOWOVERRIDE",
						},
						"userdata_name": {
							Type:        schema.TypeString,
							Computed:    true,
							Description: "The name of the linked user data.",
						},
						"userdata_params": {
							Type:        schema.TypeString,
							Computed:    true,
							Description: "The parameters of the linked user data.",
						},
					},
				},
			},

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

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

	if err := verifyTemplateParams(d); err != nil {
		return err
	}

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

	// Compute/set the display text
	displaytext := d.Get("display_text").(string)
	if displaytext == "" {
		displaytext = name
	}

	// Create a new parameter struct
	p := cs.Template.NewRegisterTemplateParams(
		displaytext,
		d.Get("format").(string),
		d.Get("hypervisor").(string),
		name,
		d.Get("url").(string),
	)

	// Retrieve the os_type ID
	ostypeid, e := retrieveID(cs, "os_type", d.Get("os_type").(string))
	if e == nil {
		p.SetOstypeid(ostypeid)
	}

	// Set optional parameters
	if v, ok := d.GetOk("is_dynamically_scalable"); ok {
		p.SetIsdynamicallyscalable(v.(bool))
	}

	if v, ok := d.GetOk("is_extractable"); ok {
		p.SetIsextractable(v.(bool))
	}

	if v, ok := d.GetOk("is_featured"); ok {
		p.SetIsfeatured(v.(bool))
	}

	if v, ok := d.GetOk("is_public"); ok {
		p.SetIspublic(v.(bool))
	}

	if v, ok := d.GetOk("password_enabled"); ok {
		p.SetPasswordenabled(v.(bool))
	}

	if v, ok := d.GetOk("for_cks"); ok {
		p.SetForcks(v.(bool))
	}

	// Retrieve the zone ID
	if v, ok := d.GetOk("zone"); ok {
		if v.(string) != "all" {
			zoneid, e := retrieveID(cs, "zone", v.(string))
			if e != nil {
				return e.Error()
			}
			p.SetZoneid(zoneid)
		} else {
			p.SetZoneid("-1")
		}
	}

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

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

	d.SetId(r.RegisterTemplate[0].Id)

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

	// Link userdata if specified
	if err = linkUserdataToTemplate(cs, d, r.RegisterTemplate[0].Id); err != nil {
		return fmt.Errorf("Error linking userdata to template %s: %s", name, err)
	}

	// Wait until the template is ready to use, or timeout with an error...
	currentTime := time.Now().Unix()
	timeout := int64(d.Get("is_ready_timeout").(int))
	for {
		// Start with the sleep so the register action has a few seconds
		// to process the registration correctly. Without this wait
		time.Sleep(10 * time.Second)

		err := resourceCloudStackTemplateRead(d, meta)
		if err != nil {
			return err
		}

		if d.Get("is_ready").(bool) {
			return nil
		}

		if time.Now().Unix()-currentTime > timeout {
			return fmt.Errorf("Timeout while waiting for template to become ready")
		}
	}
}

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

	// Get the template details
	p := cs.Template.NewListTemplatesParams("executable")
	p.SetId(d.Id())
	p.SetShowunique(true)
	project := d.Get("project").(string)
	if project != "" {
		if !cloudstack.IsID(project) {
			id, _, err := cs.Project.GetProjectID(project)
			if err != nil {
				return err
			}
			project = id
		}
		p.SetProjectid(project)
	}

	r, err := cs.Template.ListTemplates(p)
	if err != nil {
		return err
	} else if r.Count == 0 {
		log.Printf(
			"[DEBUG] Template %s no longer exists", d.Get("name").(string))
		d.SetId("")
		return nil
	}

	t := r.Templates[0]

	d.Set("name", t.Name)
	d.Set("display_text", t.Displaytext)
	d.Set("format", t.Format)
	d.Set("hypervisor", t.Hypervisor)
	d.Set("is_dynamically_scalable", t.Isdynamicallyscalable)
	d.Set("is_extractable", t.Isextractable)
	d.Set("is_featured", t.Isfeatured)
	d.Set("is_public", t.Ispublic)
	d.Set("password_enabled", t.Passwordenabled)
	d.Set("is_ready", t.Isready)
	d.Set("for_cks", t.Forcks)

	tags := make(map[string]interface{})
	for _, tag := range t.Tags {
		tags[tag.Key] = tag.Value
	}
	d.Set("tags", tags)

	setValueOrID(d, "os_type", t.Ostypename, t.Ostypeid)
	setValueOrID(d, "project", t.Project, t.Projectid)
	setValueOrID(d, "zone", t.Zonename, t.Zoneid)

	// Read userdata link information
	if err := readUserdataFromTemplate(d, t); err != nil {
		return fmt.Errorf("Error reading userdata link from template: %s", err)
	}

	return nil
}

func resourceCloudStackTemplateUpdate(d *schema.ResourceData, meta interface{}) error {
	cs := meta.(*cloudstack.CloudStackClient)
	name := d.Get("name").(string)

	// Create a new parameter struct
	p := cs.Template.NewUpdateTemplateParams(d.Id())

	if d.HasChange("name") {
		p.SetName(name)
	}

	if d.HasChange("display_text") {
		p.SetDisplaytext(d.Get("display_text").(string))
	}

	if d.HasChange("format") {
		p.SetFormat(d.Get("format").(string))
	}

	if d.HasChange("is_dynamically_scalable") {
		p.SetIsdynamicallyscalable(d.Get("is_dynamically_scalable").(bool))
	}

	if d.HasChange("os_type") {
		ostypeid, e := retrieveID(cs, "os_type", d.Get("os_type").(string))
		if e != nil {
			return e.Error()
		}
		p.SetOstypeid(ostypeid)
	}

	if d.HasChange("password_enabled") {
		p.SetPasswordenabled(d.Get("password_enabled").(bool))
	}

	_, err := cs.Template.UpdateTemplate(p)
	if err != nil {
		return fmt.Errorf("Error updating template %s: %s", name, err)
	}

	if d.HasChange("tags") {
		if err := updateTags(cs, d, "Template"); err != nil {
			return fmt.Errorf("Error updating tags on template %s: %s", name, err)
		}
	}

	if d.HasChange("userdata_link") {
		if err := updateUserdataLink(cs, d); err != nil {
			return fmt.Errorf("Error updating userdata link for template %s: %s", name, err)
		}
	}

	return resourceCloudStackTemplateRead(d, meta)
}

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

	// Create a new parameter struct
	p := cs.Template.NewDeleteTemplateParams(d.Id())

	// Delete the template
	log.Printf("[INFO] Deleting template: %s", d.Get("name").(string))
	_, err := cs.Template.DeleteTemplate(p)
	if 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 deleting template %s: %s", d.Get("name").(string), err)
	}
	return nil
}

func verifyTemplateParams(d *schema.ResourceData) error {
	format := d.Get("format").(string)
	if format != "OVA" && format != "QCOW2" && format != "RAW" && format != "VHD" && format != "VMDK" {
		return fmt.Errorf(
			"%s is not a valid format. Valid options are 'OVA','QCOW2', 'RAW', 'VHD' and 'VMDK'", format)
	}

	return nil
}

func linkUserdataToTemplate(cs *cloudstack.CloudStackClient, d *schema.ResourceData, templateID string) error {
	userdataLinks := d.Get("userdata_link").([]interface{})
	if len(userdataLinks) == 0 {
		return nil
	}

	userdataLink := userdataLinks[0].(map[string]interface{})

	p := cs.Template.NewLinkUserDataToTemplateParams()
	p.SetTemplateid(templateID)
	p.SetUserdataid(userdataLink["userdata_id"].(string))

	if policy, ok := userdataLink["userdata_policy"].(string); ok && policy != "" {
		p.SetUserdatapolicy(policy)
	}

	_, err := cs.Template.LinkUserDataToTemplate(p)
	return err
}

func readUserdataFromTemplate(d *schema.ResourceData, template *cloudstack.Template) error {
	if template.Userdataid == "" {
		d.Set("userdata_link", []interface{}{})
		return nil
	}

	userdataLink := map[string]interface{}{
		"userdata_id":     template.Userdataid,
		"userdata_name":   template.Userdataname,
		"userdata_params": template.Userdataparams,
	}

	if existingLinks := d.Get("userdata_link").([]interface{}); len(existingLinks) > 0 {
		if existingLink, ok := existingLinks[0].(map[string]interface{}); ok {
			if policy, exists := existingLink["userdata_policy"]; exists {
				userdataLink["userdata_policy"] = policy
			}
		}
	}

	d.Set("userdata_link", []interface{}{userdataLink})
	return nil
}

func updateUserdataLink(cs *cloudstack.CloudStackClient, d *schema.ResourceData) error {
	templateID := d.Id()

	oldLinks, newLinks := d.GetChange("userdata_link")
	oldLinksSlice := oldLinks.([]interface{})
	newLinksSlice := newLinks.([]interface{})

	// Check if we're removing userdata link (had one before, now empty)
	if len(oldLinksSlice) > 0 && len(newLinksSlice) == 0 {
		unlinkP := cs.Template.NewLinkUserDataToTemplateParams()
		unlinkP.SetTemplateid(templateID)

		_, err := cs.Template.LinkUserDataToTemplate(unlinkP)
		if err != nil {
			return fmt.Errorf("Error unlinking userdata from template: %s", err)
		}
		log.Printf("[DEBUG] Unlinked userdata from template: %s", templateID)
		return nil
	}

	if len(newLinksSlice) > 0 {
		newLink := newLinksSlice[0].(map[string]interface{})

		if len(oldLinksSlice) > 0 {
			oldLink := oldLinksSlice[0].(map[string]interface{})

			if oldLink["userdata_id"].(string) == newLink["userdata_id"].(string) {
				oldPolicy := ""
				newPolicy := ""

				if p, ok := oldLink["userdata_policy"].(string); ok {
					oldPolicy = p
				}
				if p, ok := newLink["userdata_policy"].(string); ok {
					newPolicy = p
				}

				if oldPolicy == newPolicy {
					log.Printf("[DEBUG] Userdata link unchanged, skipping API call")
					return nil
				}
			}

			unlinkP := cs.Template.NewLinkUserDataToTemplateParams()
			unlinkP.SetTemplateid(templateID)

			_, err := cs.Template.LinkUserDataToTemplate(unlinkP)
			if err != nil {
				log.Printf("[DEBUG] Error unlinking existing userdata (this may be normal): %s", err)
			}
		}

		return linkUserdataToTemplate(cs, d, templateID)
	}

	return nil
}
