/*
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"

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

// 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) {
	instanceType, err := m.get(metadataTypeInstanceType)
	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")
}
