/*
Copyright 2016 The Kubernetes Authors.

Licensed 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 (
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"regexp"

	"github.com/d2g/dhcp4"
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/types"
	cloudprovider "k8s.io/cloud-provider"
	"k8s.io/klog"
)

type metadata struct {
	dhcpServer string
	zone       string
}

type metadataType string

const (
	metadataTypeHostname     metadataType = "local-hostname"
	metadataTypeExternalIP   metadataType = "public-ipv4"
	metadataTypeInternalIP   metadataType = "local-ipv4"
	metadataTypeInstanceID   metadataType = "instance-id"
	metadataTypeInstanceType metadataType = "service-offering"
	metadataTypeZone         metadataType = "availability-zone"
)

var labelInvalidCharsRegex *regexp.Regexp = regexp.MustCompile(`([^A-Za-z0-9][^-A-Za-z0-9_.]*)?[^A-Za-z0-9]`)

// NodeAddresses returns the addresses of the specified instance.
func (m *metadata) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.NodeAddress, error) {
	externalIP, err := m.get(metadataTypeExternalIP)
	if err != nil {
		return nil, fmt.Errorf("could not get external IP: %v", err)
	}

	internalIP, err := m.get(metadataTypeInternalIP)
	if err != nil {
		return nil, fmt.Errorf("could not get internal IP: %v", err)
	}

	addresses := []v1.NodeAddress{
		{Type: v1.NodeExternalIP, Address: externalIP},
		{Type: v1.NodeInternalIP, Address: internalIP},
	}

	hostname, err := m.get(metadataTypeHostname)
	if err != nil {
		return nil, fmt.Errorf("could not get hostname: %v", err)
	}
	if hostname != "" {
		addresses = append(addresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
	}

	return addresses, nil
}

// NodeAddressesByProviderID returns the addresses of the specified instance.
func (m *metadata) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) {
	return nil, errors.New("NodeAddressesByProviderID not implemented")
}

// InstanceID returns the cloud provider ID of the specified instance.
func (m *metadata) InstanceID(ctx context.Context, name types.NodeName) (string, error) {
	instanceID, err := m.get(metadataTypeInstanceID)
	if err != nil {
		return "", fmt.Errorf("could not get instance ID: %v", err)
	}

	zone, err := m.get(metadataTypeZone)
	if err != nil {
		return "", fmt.Errorf("could not get zone: %v", err)
	}

	return "/" + zone + "/" + instanceID, nil
}

// InstanceType returns the type of the specified instance.
func (m *metadata) InstanceType(ctx context.Context, name types.NodeName) (string, error) {
	instanceTypeCS, err := m.get(metadataTypeInstanceType)

	// Replace everything that doesn't match the metadata.labels regex
	instanceType := labelInvalidCharsRegex.ReplaceAllString(instanceTypeCS, ``)

	if err != nil {
		return "", fmt.Errorf("could not get instance type: %v", err)
	}

	return instanceType, nil
}

// InstanceTypeByProviderID returns the type of the specified instance.
func (m *metadata) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) {
	return "", errors.New("InstanceTypeByProviderID not implemented")
}

// AddSSHKeyToAllInstances is currently not implemented.
func (m *metadata) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error {
	return cloudprovider.NotImplemented
}

// CurrentNodeName returns the name of the node we are currently running on.
func (m *metadata) CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error) {
	return types.NodeName(hostname), nil
}

// InstanceExistsByProviderID returns if the instance still exists.
func (m *metadata) InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) {
	return false, errors.New("InstanceExistsByProviderID not implemented")
}

// InstanceShutdownByProviderID returns if the instance is shutdown.
func (m *metadata) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) {
	return false, cloudprovider.NotImplemented
}

// GetZone returns the Zone containing the region that the program is running in.
func (m *metadata) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
	zone := cloudprovider.Zone{}

	if m.zone == "" {
		zoneName, err := m.get(metadataTypeZone)
		if err != nil {
			return zone, fmt.Errorf("could not get zone: %v", err)
		}

		m.zone = zoneName
	}

	klog.V(2).Infof("Current zone is %v", zone)
	zone.FailureDomain = m.zone
	zone.Region = m.zone

	return zone, nil
}

// GetZoneByProviderID returns the Zone, found by using the provider ID.
func (m *metadata) GetZoneByProviderID(ctx context.Context, providerID string) (cloudprovider.Zone, error) {
	return cloudprovider.Zone{}, errors.New("GetZoneByProviderID not implemented")
}

// GetZoneByNodeName returns the Zone, found by using the node name.
func (m *metadata) GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) (cloudprovider.Zone, error) {
	return cloudprovider.Zone{}, errors.New("GetZoneByNodeName not implemented")
}

func (m *metadata) get(mdType metadataType) (string, error) {
	url := fmt.Sprintf("http://%s/latest/meta-data/%s", m.dhcpServer, mdType)

	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("error reading metadata: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unexpected HTTP status: %d", resp.StatusCode)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("error reading response body: %d", resp.StatusCode)
	}

	return string(data), nil
}

func findDHCPServer() (string, error) {
	nics, err := net.Interfaces()
	if err != nil {
		return "", fmt.Errorf("could not get interfaces: %v", err)
	}

	for _, nic := range nics {
		if nic.Flags&net.FlagUp == 1 && nic.Flags&net.FlagLoopback == 0 && nic.Flags&net.FlagPointToPoint == 0 {
			addrs, err := nic.Addrs()
			if err != nil {
				return "", fmt.Errorf("error reading IP addresses from interface %v: %v", nic.Name, err)
			}

			if addrs != nil {
				client, err := newDHCPClient(&nic)
				if err != nil {
					return "", fmt.Errorf("error creating new DHCP client: %v", err)
				}

				discoverPacket, err := client.SendDiscoverPacket()
				if err != nil {
					return "", fmt.Errorf("error sending DHCP discover package: %v", err)
				}

				offerPacket, err := client.GetOffer(&discoverPacket)
				if err != nil {
					return "", fmt.Errorf("error receiving DHCP offer package: %v", err)
				}

				offerPacketOptions := offerPacket.ParseOptions()

				if ipaddr, ok := offerPacketOptions[dhcp4.OptionServerIdentifier]; ok {
					return net.IP(ipaddr).String(), nil
				}
			}
		}
	}

	return "", errors.New("no server found")
}
