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

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

const none = "none"

func resourceCloudStackNetwork() *schema.Resource {
	aclidSchema := &schema.Schema{
		Type:     schema.TypeString,
		Optional: true,
		Default:  none,
	}

	aclidSchema.StateFunc = func(v interface{}) string {
		value := v.(string)

		if value == none {
			aclidSchema.ForceNew = true
		} else {
			aclidSchema.ForceNew = false
		}

		return value
	}

	return &schema.Resource{
		Create: resourceCloudStackNetworkCreate,
		Read:   resourceCloudStackNetworkRead,
		Update: resourceCloudStackNetworkUpdate,
		Delete: resourceCloudStackNetworkDelete,
		Importer: &schema.ResourceImporter{
			State: importStatePassthrough,
		},

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

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

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

			"ip6cidr": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				StateFunc: func(v interface{}) string {
					s, ok := v.(string)
					if !ok {
						return ""
					}

					// Leave empty value unchanged.
					if s == "" {
						return s
					}

					// Parse and canonicalize the IPv6 CIDR. If parsing fails,
					// return the original string so invalid input is not altered.
					_, ipnet, err := net.ParseCIDR(s)
					if err != nil {
						return s
					}

					return ipnet.String()
				},
			},

			"gateway": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				RequiredWith: []string{"cidr"},
			},

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

			"startip": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				RequiredWith: []string{"cidr"},
			},

			"endip": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				RequiredWith: []string{"cidr"},
			},

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

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

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

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

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

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

			"acl_id": aclidSchema,

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

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

			"source_nat_ip_address": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"source_nat_ip_id": {
				Type:     schema.TypeString,
				Computed: true,
			},

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

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

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

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

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

	// Retrieve the network_offering ID
	networkofferingid, e := retrieveID(cs, "network_offering", d.Get("network_offering").(string))
	if e != nil {
		return e.Error()
	}

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

	// Create a new parameter struct
	p := cs.Network.NewCreateNetworkParams(name, networkofferingid, zoneid)

	if displaytext, ok := d.GetOk("display_text"); ok {
		p.SetDisplaytext(displaytext.(string))
	} else {
		p.SetDisplaytext(name)
	}

	// Get the network offering to check if it supports specifying IP ranges
	no, _, err := cs.NetworkOffering.GetNetworkOfferingByID(networkofferingid)
	if err != nil {
		return err
	}

	if _, ok := d.GetOk("cidr"); ok {
		m, err := parseCIDR(d, no.Specifyipranges)
		if err != nil {
			return err
		}

		// Set the needed IP config
		p.SetGateway(m["gateway"])
		p.SetNetmask(m["netmask"])

		// Only set the start IP if we have one
		if startip, ok := m["startip"]; ok {
			p.SetStartip(startip)
		}

		// Only set the end IP if we have one
		if endip, ok := m["endip"]; ok {
			p.SetEndip(endip)
		}
	}

	// IPv6 support
	if ip6cidr, ok := d.GetOk("ip6cidr"); ok {
		m6, err := parseCIDRv6(d, no.Specifyipranges)
		if err != nil {
			return err
		}

		p.SetIp6cidr(ip6cidr.(string))

		// Only set the start IPv6 if we have one
		if startipv6, ok := m6["startipv6"]; ok {
			p.SetStartipv6(startipv6)
		}

		// Only set the ipv6 gateway if we have one
		if ip6gateway, ok := m6["ip6gateway"]; ok {
			p.SetIp6gateway(ip6gateway)
		}

		// Only set the end IPv6 if we have one
		if endipv6, ok := m6["endipv6"]; ok {
			p.SetEndipv6(endipv6)
		}
	}

	// Set the network domain if we have one
	if networkDomain, ok := d.GetOk("network_domain"); ok {
		p.SetNetworkdomain(networkDomain.(string))
	}

	if vlan, ok := d.GetOk("vlan"); ok {
		p.SetVlan(strconv.Itoa(vlan.(int)))
	}

	// Bypass VLAN overlap check if necessary
	if bypassVlanOverlapCheck, ok := d.GetOk("bypass_vlan_overlap_check"); ok {
		p.SetBypassvlanoverlapcheck(bypassVlanOverlapCheck.(bool))
	}

	// Check is this network needs to be created in a VPC
	if vpcid, ok := d.GetOk("vpc_id"); ok {
		// Set the vpc id
		p.SetVpcid(vpcid.(string))

		// Since we're in a VPC, check if we want to associate an ACL list
		if aclid, ok := d.GetOk("acl_id"); ok && aclid.(string) != none {
			// Set the acl ID
			p.SetAclid(aclid.(string))
		}

		// If no project is explicitly set, try to inherit it from the VPC
		if _, ok := d.GetOk("project"); !ok {
			// Get the VPC to retrieve its project
			// Use listall to search across all projects
			vpcParams := cs.VPC.NewListVPCsParams()
			vpcParams.SetId(vpcid.(string))
			vpcParams.SetListall(true)
			vpcList, err := cs.VPC.ListVPCs(vpcParams)
			if err == nil && vpcList.Count > 0 && vpcList.VPCs[0].Projectid != "" {
				log.Printf("[DEBUG] Inheriting project %s from VPC %s", vpcList.VPCs[0].Projectid, vpcid.(string))
				p.SetProjectid(vpcList.VPCs[0].Projectid)
			}
		}
	}

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

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

	d.SetId(r.Id)

	// Set tags if necessary
	if err = setTags(cs, d, "network"); err != nil {
		return fmt.Errorf("Error setting tags: %v", err)
	}

	if d.Get("source_nat_ip").(bool) {
		// Create a new parameter struct
		p := cs.Address.NewAssociateIpAddressParams()

		// Set required options
		p.SetNetworkid(r.Id)
		p.SetZoneid(zoneid)

		if vpcid, ok := d.GetOk("vpc_id"); ok {
			// Set the vpcid
			p.SetVpcid(vpcid.(string))
		}

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

		// Associate a new IP address
		ip, err := cs.Address.AssociateIpAddress(p)
		if err != nil {
			return fmt.Errorf("Error associating a new IP address: %s", err)
		}
		d.Set("source_nat_ip_address", ip.Ipaddress)
		d.Set("source_nat_ip_id", ip.Id)

		// Set the additional partial
	}

	return resourceCloudStackNetworkRead(d, meta)
}

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

	// Get the network details
	// First try with the project from state (if any)
	project := d.Get("project").(string)
	n, count, err := cs.Network.GetNetworkByID(
		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 VPC
	if count == 0 && project == "" {
		n, count, err = cs.Network.GetNetworkByID(
			d.Id(),
			cloudstack.WithProject("-1"),
		)
	}

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

		return err
	}

	d.Set("name", n.Name)
	d.Set("display_text", n.Displaytext)
	d.Set("cidr", n.Cidr)
	d.Set("gateway", n.Gateway)
	d.Set("network_domain", n.Networkdomain)
	d.Set("vpc_id", n.Vpcid)

	// Always set IPv6 fields to detect drift when IPv6 is removed server-side
	d.Set("ip6cidr", n.Ip6cidr)
	d.Set("ip6gateway", n.Ip6gateway)

	// Note: CloudStack API may not return startipv6 and endipv6 fields
	// These are typically only set during network creation

	if n.Aclid == "" {
		n.Aclid = none
	}
	d.Set("acl_id", n.Aclid)

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

	setValueOrID(d, "network_offering", n.Networkofferingname, n.Networkofferingid)
	setValueOrID(d, "project", n.Project, n.Projectid)
	setValueOrID(d, "zone", n.Zonename, n.Zoneid)

	if d.Get("source_nat_ip").(bool) {
		ip, count, err := cs.Address.GetPublicIpAddressByID(
			d.Get("source_nat_ip_id").(string),
			cloudstack.WithProject(d.Get("project").(string)),
		)
		if err != nil {
			if count == 0 {
				log.Printf(
					"[DEBUG] Source NAT IP with ID %s is no longer associated", d.Id())
				d.Set("source_nat_ip", false)
				d.Set("source_nat_ip_id", "")
				return nil
			}

			return err
		}

		if n.Id != ip.Associatednetworkid {
			d.Set("source_nat_ip", false)
			d.Set("source_nat_ip_id", "")
		}
	}

	return nil
}

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

	// Create a new parameter struct
	p := cs.Network.NewUpdateNetworkParams(d.Id())

	// Check if the name or display text is changed
	if d.HasChange("name") || d.HasChange("display_text") {
		p.SetName(name)

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

	// Check if the cidr is changed
	if d.HasChange("cidr") {
		p.SetGuestvmcidr(d.Get("cidr").(string))
	}

	// Check if the network domain is changed
	if d.HasChange("network_domain") {
		p.SetNetworkdomain(d.Get("network_domain").(string))
	}

	// Check if the network offering is changed
	if d.HasChange("network_offering") {
		// Retrieve the network_offering ID
		networkofferingid, e := retrieveID(cs, "network_offering", d.Get("network_offering").(string))
		if e != nil {
			return e.Error()
		}
		// Set the new network offering
		p.SetNetworkofferingid(networkofferingid)
	}

	// Update the network
	_, err := cs.Network.UpdateNetwork(p)
	if err != nil {
		return fmt.Errorf(
			"Error updating network %s: %s", name, err)
	}

	// Replace the ACL if the ID has changed
	if d.HasChange("acl_id") {
		p := cs.NetworkACL.NewReplaceNetworkACLListParams(d.Get("acl_id").(string))
		p.SetNetworkid(d.Id())

		_, err := cs.NetworkACL.ReplaceNetworkACLList(p)
		if err != nil {
			return fmt.Errorf("Error replacing ACL: %s", err)
		}
	}

	// Update tags if they have changed
	if d.HasChange("tags") {
		if err := updateTags(cs, d, "Network"); err != nil {
			return fmt.Errorf("Error updating tags on ACL %s: %s", name, err)
		}
	}

	return resourceCloudStackNetworkRead(d, meta)
}

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

	// Create a new parameter struct
	p := cs.Network.NewDeleteNetworkParams(d.Id())

	// Delete the network
	_, err := cs.Network.DeleteNetwork(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 network %s: %s", d.Get("name").(string), err)
	}
	return nil
}

func parseCIDR(d *schema.ResourceData, specifyiprange bool) (map[string]string, error) {
	m := make(map[string]string, 4)

	cidr := d.Get("cidr").(string)
	ip, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, fmt.Errorf("Unable to parse cidr %s: %s", cidr, err)
	}

	msk := ipnet.Mask
	sub := ip.Mask(msk)

	m["netmask"] = fmt.Sprintf("%d.%d.%d.%d", msk[0], msk[1], msk[2], msk[3])

	if gateway, ok := d.GetOk("gateway"); ok {
		m["gateway"] = gateway.(string)
	} else {
		m["gateway"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+1)
	}

	if startip, ok := d.GetOk("startip"); ok {
		m["startip"] = startip.(string)
	} else if specifyiprange {
		m["startip"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+2)
	}

	if endip, ok := d.GetOk("endip"); ok {
		m["endip"] = endip.(string)
	} else if specifyiprange {
		m["endip"] = fmt.Sprintf("%d.%d.%d.%d",
			sub[0]+(0xff-msk[0]), sub[1]+(0xff-msk[1]), sub[2]+(0xff-msk[2]), sub[3]+(0xff-msk[3]-1))
	}

	return m, nil
}

// addToIPv6 adds an integer offset to an IPv6 address with proper carry across all bytes.
// Returns a new net.IP with the result.
func addToIPv6(ip net.IP, offset uint64) net.IP {
	result := make(net.IP, len(ip))
	copy(result, ip)

	carry := offset
	// Start from the least significant byte (rightmost) and work backwards
	for i := len(result) - 1; i >= 0 && carry > 0; i-- {
		sum := uint64(result[i]) + carry
		result[i] = byte(sum & 0xff)
		carry = sum >> 8
	}

	return result
}

// validateIPv6InCIDR verifies that a user-supplied IPv6 address parses and falls
// within the given network. It returns a clear local error instead of letting an
// out-of-subnet value surface as an opaque CloudStack API failure at apply time.
func validateIPv6InCIDR(field, value string, ipnet *net.IPNet) error {
	ip := net.ParseIP(value)
	if ip == nil {
		return fmt.Errorf("%s %q is not a valid IP address", field, value)
	}
	if !ipnet.Contains(ip) {
		return fmt.Errorf("%s %q is not within ip6cidr %s", field, value, ipnet.String())
	}
	return nil
}

func parseCIDRv6(d *schema.ResourceData, specifyiprange bool) (map[string]string, error) {
	m := make(map[string]string, 4)

	cidr := d.Get("ip6cidr").(string)
	ip, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, fmt.Errorf("Unable to parse cidr %s: %s", cidr, err)
	}

	// Validate that this is actually an IPv6 CIDR
	if ip.To4() != nil {
		return nil, fmt.Errorf("ip6cidr must be an IPv6 CIDR, got IPv4: %s", cidr)
	}
	if len(ipnet.Mask) != net.IPv6len {
		return nil, fmt.Errorf("ip6cidr must be an IPv6 CIDR with 16-byte mask, got %d bytes: %s", len(ipnet.Mask), cidr)
	}

	// Validate prefix length to ensure we have enough addresses for gateway/start/end
	ones, _ := ipnet.Mask.Size()
	if specifyiprange {
		// When specifyiprange is true, we need at least 3 addresses:
		// - gateway (network + 1)
		// - start IP (network + 2)
		// - end IP (network + 3 or more)
		// This requires a /126 or larger prefix (4 addresses minimum)
		if ones > 126 {
			return nil, fmt.Errorf("ip6cidr prefix /%d is too small for automatic IP range generation; minimum is /126 (4 addresses)", ones)
		}
	} else {
		// When specifyiprange is false, we only need the gateway (network + 1)
		// This requires a /127 or larger prefix (2 addresses minimum)
		if ones > 127 {
			return nil, fmt.Errorf("ip6cidr prefix /%d is too small for automatic gateway generation; minimum is /127 (2 addresses)", ones)
		}
	}

	if gateway, ok := d.GetOk("ip6gateway"); ok {
		gw := gateway.(string)
		if err := validateIPv6InCIDR("ip6gateway", gw, ipnet); err != nil {
			return nil, err
		}
		m["ip6gateway"] = gw
	} else {
		// Default gateway to network address + 1 (e.g., 2001:db8::1)
		gwip := addToIPv6(ipnet.IP, 1)
		m["ip6gateway"] = gwip.String()
	}

	if startipv6, ok := d.GetOk("startipv6"); ok {
		start := startipv6.(string)
		if err := validateIPv6InCIDR("startipv6", start, ipnet); err != nil {
			return nil, err
		}
		m["startipv6"] = start
	} else if specifyiprange {
		// Default start IP to network address + 2
		startip := addToIPv6(ipnet.IP, 2)
		m["startipv6"] = startip.String()
	}

	if endip, ok := d.GetOk("endipv6"); ok {
		end := endip.(string)
		if err := validateIPv6InCIDR("endipv6", end, ipnet); err != nil {
			return nil, err
		}
		m["endipv6"] = end
	} else if specifyiprange {
		ip16 := ipnet.IP.To16()
		if ip16 == nil {
			return nil, fmt.Errorf("cidr not valid for ipv6")
		}

		last := make(net.IP, len(ip16))
		copy(last, ip16)

		for i := range ip16 {
			// Perform bitwise OR with the inverse of the mask
			last[i] |= ^ipnet.Mask[i]
		}
		m["endipv6"] = last.String()
	}

	return m, nil
}
