package main

import (
	"fmt"
	"os"
	"strings"

	//	"encoding/json"

	"github.com/UpCloudLtd/upcloud-go-api/upcloud"
	"github.com/UpCloudLtd/upcloud-go-api/upcloud/request"
	"github.com/UpCloudLtd/upcloud-go-api/upcloud/service"
)

func getFloatIP(s *service.Service, floatIP string, datacfg *DataConfig) (*upcloud.IPAddress,error) {
	ip := floatIP
	if ip == "" {
		ip = datacfg.FloatIP
	}
	ipinfo, err := s.GetIPAddressDetails(&request.GetIPAddressDetailsRequest{
		Address: ip,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "error getting info %s: %#v\n", floatIP, err)
		return nil,err
	}
	return ipinfo,nil
}
func moveFloatIP(s *service.Service, data []string, datacfg *DataConfig) error {
	// err := s.ReleaseIPAddress(&request.ReleaseIPAddressRequest{
	// 	IPAddress: uuid,
	// })
	// fmt.Fprintf(os.Stderr, "details %#v: %#v\n", uuid, err)
	targetFloatIP := ""
	targetHost := ""
	if len(data) > 0 {
		targetFloatIP = data[0]
		targetHost = data[1]
	} else {
		targetFloatIP = datacfg.FloatIP
	}
	servers, err := s.GetServers()
	if err != nil || len(servers.Servers) == 0 {
		fmt.Fprintf(os.Stderr, "Unable to get servers: %#v\n", err)
		return err
	}

	ipinfo, err := getFloatIP(s,targetFloatIP,datacfg)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error getting info %s: %#v\n", targetFloatIP, err)
		return err
	}
	 // fmt.Fprintf(os.Stderr, "ipinfo: %#v\n", ipinfo)
	 //  fmt.Printf("Retrieved %d servers\n", len(servers.Servers))
	 // fmt.Println("Deleting all servers")
	currentFloatIP := ""
	for _, server := range servers.Servers {
		if datacfg.HostPrefix != "" && ! strings.Contains(server.Hostname,datacfg.HostPrefix) {
			continue
		}
		if ipinfo.ServerUUID == server.UUID {
			fmt.Fprintf(os.Stderr, "%s Located in %s %s:%s Server: %s) \n", targetFloatIP, ipinfo.PTRRecord, server.Hostname, ipinfo.MAC, ipinfo.ServerUUID)
			currentFloatIP = server.Hostname
			break
		}
	}
	if currentFloatIP == "" {
		fmt.Fprintf(os.Stderr, "%s Not in use in %s \n", targetFloatIP, ipinfo.PTRRecord)
	}
	for _, server := range servers.Servers {
		if (datacfg.HostPrefix != "" && ! strings.Contains(server.Hostname,datacfg.HostPrefix)) || ipinfo.ServerUUID == server.UUID {
			continue
		}
		var target_srv ServerConfig
		if targetHost == "" {
			for _,srv := range datacfg.Servers {
				if server.Hostname == srv.Hostname && srv.UseFloatIP {
					target_srv = srv
					break
				}
			}
		} else {
			if server.Hostname == targetHost {
				target_srv.Hostname = targetHost
			}
		}
		if target_srv.Hostname == "" {
			continue
		}
		info,err := s.GetServerDetails(&request.GetServerDetailsRequest{
			UUID: server.UUID,
		}) 
		if err != nil {
			continue
		}
		target_IP := ""
		target_MAC := ""
		for i := 0; i < len(info.Networking.Interfaces); i++ {
			if  info.Networking.Interfaces[i].Type == upcloud.NetworkTypePublic {
		    for _,ip := range info.Networking.Interfaces[i].IPAddresses {
					if  ip.Address != targetFloatIP {
						target_IP = ip.Address
						break
					}
				}
				target_MAC=info.Networking.Interfaces[i].MAC
				break
			}
		}
		if target_IP != "" && target_MAC != "" {
			ptr := fmt.Sprintf("%s.%s.upcloud.host", target_IP, info.Zone)
			 newIP,err := s.ModifyIPAddress(&request.ModifyIPAddressRequest{
				 IPAddress: targetFloatIP,
				 PTRRecord: ptr,
				 MAC: target_MAC,
			 })
			 if err != nil {
				fmt.Fprintf(os.Stderr, "error %s: %#v\n", targetFloatIP, err) 
			 } else {
				fmt.Fprintf(os.Stderr, "%s Moved -> %s %s:%s Server: %s \n", newIP.Address, newIP.PTRRecord, target_srv.Hostname, newIP.MAC, server.UUID) 
			 }
			break
		}
	}
	return err
}