//
// 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"
	"regexp"
	"strconv"
	"strings"
	"time"

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

func resourceCloudStackLoadBalancerRule() *schema.Resource {
	return &schema.Resource{
		Create: resourceCloudStackLoadBalancerRuleCreate,
		Read:   resourceCloudStackLoadBalancerRuleRead,
		Update: resourceCloudStackLoadBalancerRuleUpdate,
		Delete: resourceCloudStackLoadBalancerRuleDelete,

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

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

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

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

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

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

			"private_port": {
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"public_port": {
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

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

			"member_ids": {
				Type:     schema.TypeSet,
				Required: true,
				ForceNew: false,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

			"cidrlist": {
				Type:     schema.TypeSet,
				Optional: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

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

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

	// Make sure all required parameters are there
	if err := verifyLoadBalancerRule(d); err != nil {
		return err
	}

	// Create a new parameter struct
	p := cs.LoadBalancer.NewCreateLoadBalancerRuleParams(
		d.Get("algorithm").(string),
		d.Get("name").(string),
		d.Get("private_port").(int),
		d.Get("public_port").(int),
	)

	// Don't autocreate a firewall rule, use a resource if needed
	p.SetOpenfirewall(false)

	// Set the description
	if description, ok := d.GetOk("description"); ok {
		p.SetDescription(description.(string))
	} else {
		p.SetDescription(d.Get("name").(string))
	}

	if networkid, ok := d.GetOk("network_id"); ok {
		// Set the network id
		p.SetNetworkid(networkid.(string))
	}

	// Set the protocol
	if protocol, ok := d.GetOk("protocol"); ok {
		p.SetProtocol(protocol.(string))
	}

	// Set CIDR list
	if cidr, ok := d.GetOk("cidrlist"); ok {
		var cidrList []string
		for _, id := range cidr.(*schema.Set).List() {
			cidrList = append(cidrList, id.(string))
		}

		p.SetCidrlist(cidrList)
	}

	// Set the ipaddress id
	p.SetPublicipid(d.Get("ip_address_id").(string))

	// Create the load balancer rule
	r, err := cs.LoadBalancer.CreateLoadBalancerRule(p)
	if err != nil {
		return err
	}

	// Set the load balancer rule ID and set partials
	d.SetId(r.Id)

	if certificateID, ok := d.GetOk("certificate_id"); ok {
		// Create a new parameter struct
		cp := cs.LoadBalancer.NewAssignCertToLoadBalancerParams(certificateID.(string), r.Id)
		if _, err := cs.LoadBalancer.AssignCertToLoadBalancer(cp); err != nil {
			return err
		}
	}

	// Create a new parameter struct
	mp := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id)

	var mbs []string
	for _, id := range d.Get("member_ids").(*schema.Set).List() {
		mbs = append(mbs, id.(string))
	}

	mp.SetVirtualmachineids(mbs)

	_, err = cs.LoadBalancer.AssignToLoadBalancerRule(mp)
	if err != nil {
		return err
	}

	return resourceCloudStackLoadBalancerRuleRead(d, meta)
}

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

	// Get the load balancer details
	lb, count, err := cs.LoadBalancer.GetLoadBalancerRuleByID(
		d.Id(),
		cloudstack.WithProject(d.Get("project").(string)),
	)
	if err != nil {
		if count == 0 {
			log.Printf("[DEBUG] Load balancer rule %s does no longer exist", d.Get("name").(string))
			d.SetId("")
			return nil
		}

		return err
	}

	public_port, err := strconv.Atoi(lb.Publicport)
	if err != nil {
		return err
	}

	private_port, err := strconv.Atoi(lb.Privateport)
	if err != nil {
		return err
	}

	d.Set("name", lb.Name)
	d.Set("ip_address_id", lb.Publicipid)
	d.Set("algorithm", lb.Algorithm)
	d.Set("public_port", public_port)
	d.Set("private_port", private_port)
	d.Set("protocol", lb.Protocol)

	// Only set cidr if user specified it to avoid spurious diffs
	delimiters := regexp.MustCompile(`\s*,\s*|\s+`)
	if _, ok := d.GetOk("cidrlist"); ok {
		d.Set("cidrlist", delimiters.Split(lb.Cidrlist, -1))
	}

	// Only set network if user specified it to avoid spurious diffs
	if _, ok := d.GetOk("network_id"); ok {
		d.Set("network_id", lb.Networkid)
	}

	setValueOrID(d, "project", lb.Project, lb.Projectid)

	p := cs.LoadBalancer.NewListLoadBalancerRuleInstancesParams(d.Id())
	l, err := cs.LoadBalancer.ListLoadBalancerRuleInstances(p)
	if err != nil {
		return err
	}

	var mbs []string
	for _, i := range l.LoadBalancerRuleInstances {
		mbs = append(mbs, i.Id)
	}

	asgCheckParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
	asgCheckParams.SetLbruleid(d.Id())

	asgGroups, err := cs.AutoScale.ListAutoScaleVmGroups(asgCheckParams)
	if err != nil {
		log.Printf("[WARN] Failed to check for autoscale VM groups during read: %s", err)
	}

	if len(asgGroups.AutoScaleVmGroups) > 0 {
		log.Printf("[DEBUG] Load balancer rule %s is managed by %d autoscale VM group(s), current members: %v",
			d.Id(), len(asgGroups.AutoScaleVmGroups), mbs)

		if currentMemberIds, ok := d.GetOk("member_ids"); ok {
			currentSet := currentMemberIds.(*schema.Set)
			if currentSet.Len() == 0 && len(mbs) > 0 {
				d.Set("member_ids", []string{})
				return nil
			}
		}
	}

	d.Set("member_ids", mbs)

	return nil
}

func waitForASGsToBeDisabled(cs *cloudstack.CloudStackClient, lbRuleID string) error {
	log.Printf("[DEBUG] Waiting for autoscale VM groups using load balancer rule %s to be disabled", lbRuleID)

	maxRetries := 60 // 60 * 2 seconds = 120 seconds max wait (longer for Terraform-driven changes)
	for i := 0; i < maxRetries; i++ {
		listParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
		listParams.SetLbruleid(lbRuleID)

		groups, err := cs.AutoScale.ListAutoScaleVmGroups(listParams)
		if err != nil {
			log.Printf("[WARN] Failed to list autoscale VM groups: %s", err)
			time.Sleep(2 * time.Second)
			continue
		}

		allDisabled := true
		var enabledGroups []string

		for _, group := range groups.AutoScaleVmGroups {
			if group.State != "disabled" && group.State != "disable" {
				allDisabled = false
				enabledGroups = append(enabledGroups, fmt.Sprintf("%s(%s:%s)", group.Name, group.Id, group.State))
			}
		}

		if allDisabled {
			log.Printf("[INFO] All autoscale VM groups using load balancer rule %s are now disabled", lbRuleID)
			return nil
		}

		if i < maxRetries-1 {
			log.Printf("[DEBUG] Waiting for autoscale VM groups to be disabled (attempt %d/%d). Groups still enabled: %v",
				i+1, maxRetries, enabledGroups)
			time.Sleep(2 * time.Second)
		}
	}

	return fmt.Errorf("Timeout waiting for autoscale VM groups to be disabled after %d seconds", maxRetries*2)
}

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

	// Make sure all required parameters are there
	if err := verifyLoadBalancerRule(d); err != nil {
		return err
	}

	if d.HasChange("name") || d.HasChange("description") || d.HasChange("algorithm") {
		name := d.Get("name").(string)

		// Create new parameter struct
		p := cs.LoadBalancer.NewUpdateLoadBalancerRuleParams(d.Id())

		if d.HasChange("name") {
			log.Printf("[DEBUG] Name has changed for load balancer rule %s, starting update", name)

			p.SetName(name)
		}

		if d.HasChange("description") {
			log.Printf(
				"[DEBUG] Description has changed for load balancer rule %s, starting update", name)

			p.SetDescription(d.Get("description").(string))
		}

		if d.HasChange("algorithm") {
			algorithm := d.Get("algorithm").(string)

			log.Printf(
				"[DEBUG] Algorithm has changed to %s for load balancer rule %s, starting update",
				algorithm,
				name,
			)

			// Set the new Algorithm
			p.SetAlgorithm(algorithm)
		}

		_, err := cs.LoadBalancer.UpdateLoadBalancerRule(p)
		if err != nil {
			return fmt.Errorf(
				"Error updating load balancer rule %s: %s", name, err)
		}
	}

	if d.HasChange("certificate_id") {
		p := cs.LoadBalancer.NewRemoveCertFromLoadBalancerParams(d.Id())
		if _, err := cs.LoadBalancer.RemoveCertFromLoadBalancer(p); err != nil {
			return err
		}

		_, certificateID := d.GetChange("certificate_id")
		cp := cs.LoadBalancer.NewAssignCertToLoadBalancerParams(certificateID.(string), d.Id())
		if _, err := cs.LoadBalancer.AssignCertToLoadBalancer(cp); err != nil {
			return err
		}
	}

	if d.HasChange("member_ids") {
		log.Printf("[DEBUG] Load balancer rule %s member_ids change detected", d.Id())

		asgCheckParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
		asgCheckParams.SetLbruleid(d.Id())

		asgGroups, err := cs.AutoScale.ListAutoScaleVmGroups(asgCheckParams)
		if err != nil {
			log.Printf("[WARN] Failed to check for autoscale VM groups: %s", err)
		}

		if len(asgGroups.AutoScaleVmGroups) > 0 {
			log.Printf("[INFO] Load balancer rule %s is managed by %d autoscale VM group(s), handling member updates carefully",
				d.Id(), len(asgGroups.AutoScaleVmGroups))

			o, n := d.GetChange("member_ids")
			ombs, nmbs := o.(*schema.Set), n.(*schema.Set)

			setToStringList := func(s *schema.Set) []string {
				l := make([]string, s.Len())
				for i, v := range s.List() {
					l[i] = v.(string)
				}
				return l
			}

			oldMembers := setToStringList(ombs)
			newMembers := setToStringList(nmbs)

			log.Printf("[DEBUG] Terraform state - old members: %v, new members: %v", oldMembers, newMembers)

			p := cs.LoadBalancer.NewListLoadBalancerRuleInstancesParams(d.Id())
			currentInstances, err := cs.LoadBalancer.ListLoadBalancerRuleInstances(p)
			if err != nil {
				return fmt.Errorf("Error listing current load balancer members: %s", err)
			}

			var currentMembers []string
			for _, i := range currentInstances.LoadBalancerRuleInstances {
				currentMembers = append(currentMembers, i.Id)
			}

			log.Printf("[DEBUG] CloudStack actual members: %v", currentMembers)

			// If Terraform state is empty but CloudStack has members, it means autoscale is managing them
			if len(oldMembers) == 0 && len(currentMembers) > 0 {
				log.Printf("[INFO] Detected autoscale-managed members in load balancer. Skipping member updates to avoid conflicts.")
				log.Printf("[INFO] Autoscale VM groups will manage the member lifecycle automatically.")

				d.Set("member_ids", currentMembers)
				return resourceCloudStackLoadBalancerRuleRead(d, meta)
			}

			if len(newMembers) > 0 {
				log.Printf("[WARN] Explicit member_ids specified for autoscale-managed load balancer. This may conflict with autoscale operations.")

				if err := waitForASGsToBeDisabled(cs, d.Id()); err != nil {
					return fmt.Errorf("Autoscale VM groups must be disabled before modifying load balancer members: %s", err)
				}

				membersToAdd := setToStringList(nmbs.Difference(ombs))
				membersToRemove := setToStringList(ombs.Difference(nmbs))

				log.Printf("[DEBUG] Explicit member changes - to add: %v, to remove: %v", membersToAdd, membersToRemove)

				if len(membersToRemove) > 0 {
					log.Printf("[DEBUG] Removing %d explicit members from load balancer rule %s", len(membersToRemove), d.Id())
					removeParams := cs.LoadBalancer.NewRemoveFromLoadBalancerRuleParams(d.Id())
					removeParams.SetVirtualmachineids(membersToRemove)
					if _, err := cs.LoadBalancer.RemoveFromLoadBalancerRule(removeParams); err != nil {
						return fmt.Errorf("Error removing explicit members from load balancer rule %s: %s. Members: %v", d.Id(), err, membersToRemove)
					}
				}

				if len(membersToAdd) > 0 {
					log.Printf("[DEBUG] Adding %d explicit members to load balancer rule %s", len(membersToAdd), d.Id())
					addParams := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(d.Id())
					addParams.SetVirtualmachineids(membersToAdd)
					if _, err := cs.LoadBalancer.AssignToLoadBalancerRule(addParams); err != nil {
						return fmt.Errorf("Error adding explicit members to load balancer rule %s: %s. Members: %v", d.Id(), err, membersToAdd)
					}
				}
			}
		} else {
			// No autoscale groups, proceed with normal member management
			log.Printf("[DEBUG] No autoscale groups found, proceeding with normal member management")

			o, n := d.GetChange("member_ids")
			ombs, nmbs := o.(*schema.Set), n.(*schema.Set)

			setToStringList := func(s *schema.Set) []string {
				l := make([]string, s.Len())
				for i, v := range s.List() {
					l[i] = v.(string)
				}
				return l
			}

			membersToAdd := setToStringList(nmbs.Difference(ombs))
			membersToRemove := setToStringList(ombs.Difference(nmbs))

			log.Printf("[DEBUG] Members to add: %v, remove: %v", membersToAdd, membersToRemove)

			if len(membersToRemove) > 0 {
				log.Printf("[DEBUG] Removing %d members from load balancer rule %s", len(membersToRemove), d.Id())
				p := cs.LoadBalancer.NewRemoveFromLoadBalancerRuleParams(d.Id())
				p.SetVirtualmachineids(membersToRemove)
				if _, err := cs.LoadBalancer.RemoveFromLoadBalancerRule(p); err != nil {
					return fmt.Errorf("Error removing members from load balancer rule %s: %s. Members to remove: %v", d.Id(), err, membersToRemove)
				}
				log.Printf("[DEBUG] Successfully removed members from load balancer rule")
			}

			if len(membersToAdd) > 0 {
				log.Printf("[DEBUG] Adding %d members to load balancer rule %s", len(membersToAdd), d.Id())
				p := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(d.Id())
				p.SetVirtualmachineids(membersToAdd)
				if _, err := cs.LoadBalancer.AssignToLoadBalancerRule(p); err != nil {
					return fmt.Errorf("Error adding members to load balancer rule %s: %s. Members to add: %v", d.Id(), err, membersToAdd)
				}
				log.Printf("[DEBUG] Successfully added members to load balancer rule")
			}
		}
	}

	return resourceCloudStackLoadBalancerRuleRead(d, meta)
}

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

	// Create a new parameter struct
	p := cs.LoadBalancer.NewDeleteLoadBalancerRuleParams(d.Id())

	log.Printf("[INFO] Deleting load balancer rule: %s", d.Get("name").(string))
	if _, err := cs.LoadBalancer.DeleteLoadBalancerRule(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 err
		}
	}

	return nil
}

func verifyLoadBalancerRule(d *schema.ResourceData) error {
	if protocol, ok := d.GetOk("protocol"); ok {
		protocol := protocol.(string)

		switch protocol {
		case "tcp", "udp", "tcp-proxy":
			// These are supported
		default:
			return fmt.Errorf(
				"%q is not a valid protocol. Valid options are 'tcp', 'udp' of 'tcp-proxy'", protocol)
		}
	}

	return nil
}
