//
// 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/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,
				Required: true,
				ForceNew: true,
			},

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

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

			"endip": {
				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_id": {
				Type:     schema.TypeString,
				Computed: true,
			},

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

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

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

	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()
	}

	// Compute/set the display text
	displaytext, ok := d.GetOk("display_text")
	if !ok {
		displaytext = name
	}

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

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

	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)
	}

	// 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)))
	}

	// 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 assiciate an ACL list
		if aclid, ok := d.GetOk("acl_id"); ok && aclid.(string) != none {
			// Set the acl ID
			p.SetAclid(aclid.(string))
		}
	}

	// 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 network
	r, err := cs.Network.CreateNetwork(p)
	if err != nil {
		return fmt.Errorf("Error creating network %s: %s", name, err)
	}

	d.SetPartial("name")
	d.SetPartial("display_text")
	d.SetPartial("cidr")
	d.SetPartial("gateway")
	d.SetPartial("startip")
	d.SetPartial("endip")
	d.SetPartial("network_domain")
	d.SetPartial("network_offering")
	d.SetPartial("vlan")
	d.SetPartial("vpc_id")
	d.SetPartial("acl_id")
	d.SetPartial("project")
	d.SetPartial("zone")

	d.SetId(r.Id)

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

	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_id", ip.Id)

		// Set the additional partial
		d.SetPartial("source_nat_ip")
		d.SetPartial("source_nat_ip_id")
	}

	d.Partial(false)
	return resourceCloudStackNetworkRead(d, meta)
}

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

	// Get the virtual machine details
	n, count, err := cs.Network.GetNetworkByID(
		d.Id(),
		cloudstack.WithProject(d.Get("project").(string)),
	)
	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)

	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
}
