package util

import (
	"fmt"
	"log"
	"net"
	"strings"
	"time"

	"github.com/fatih/color"
)

var (
	result  string
	results = make(chan string)
)
var FastIpCache = ""

func GetFastIP(domain string, port string, enableOutput bool) string {
	proxyUrl := GetProxy()
	if proxyUrl != nil {
		return "api.leo.moe"
	}
	if FastIpCache != "" {
		return FastIpCache
	}

	ips, err := net.LookupIP(domain)
	if err != nil {
		log.Fatal("DNS resolution failed, please check your system DNS Settings")
	}

	for _, ip := range ips {
		go checkLatency(ip.String(), port)
	}

	select {
	case result = <-results:
	case <-time.After(1 * time.Second):
	}
	if result == "" {
		log.Fatal("IP connection has been timeout, please check your network")
	}
	res := strings.Split(result, "-")

	if len(ips) > 1 {
		if enableOutput {
			_, _ = fmt.Fprintf(color.Output, "%s prefered API IP - %s - %s\n",
				color.New(color.FgWhite, color.Bold).Sprintf("[NextTrace API]"),
				color.New(color.FgGreen, color.Bold).Sprintf("%s", res[0]),
				color.New(color.FgCyan, color.Bold).Sprintf("%sms", res[1]),
			)
		}
	}
	FastIpCache = res[0]
	return res[0]
}

func checkLatency(ip string, port string) {
	start := time.Now()
	if !strings.Contains(ip, ".") {
		ip = "[" + ip + "]"
	}
	conn, err := net.DialTimeout("tcp", ip+":"+port, time.Second*1)
	if err != nil {
		return
	}
	defer func(conn net.Conn) {
		err := conn.Close()
		if err != nil {
			return
		}
	}(conn)
	if result == "" {
		result = fmt.Sprintf("%s-%.2f", ip, float64(time.Since(start))/float64(time.Millisecond))
		results <- result
		return
	}
}
