//go:build !freebsd
// +build !freebsd

package utils

import (
	"context"
	"github.com/iwind/TeaGo/logs"
	"net"
	"sort"
	"syscall"
)

// ListenReuseAddr 监听可重用的端口
func ListenReuseAddr(network string, addr string) (net.Listener, error) {
	config := &net.ListenConfig{
		Control: func(network, address string, c syscall.RawConn) error {
			return c.Control(func(fd uintptr) {
				err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_REUSEPORT, 1)
				if err != nil {
					logs.Println("[LISTEN]" + err.Error())
				}
			})
		},
		KeepAlive: 0,
	}
	return config.Listen(context.Background(), network, addr)
}

// ParseAddrHost 分析地址中的主机名部分
func ParseAddrHost(addr string) string {
	if len(addr) == 0 {
		return addr
	}

	host, _, err := net.SplitHostPort(addr)
	if err != nil {
		return addr
	}
	return host
}

// MergePorts 聚合端口
// 返回 [ [fromPort, toPort], ... ]
func MergePorts(ports []int) [][2]int {
	if len(ports) == 0 {
		return nil
	}

	sort.Ints(ports)

	var result = [][2]int{}
	var lastRange = [2]int{0, 0}
	var lastPort = -1
	for _, port := range ports {
		if port <= 0 /** 只处理有效的端口 **/ || port == lastPort /** 去重 **/ {
			continue
		}

		if lastPort < 0 || port != lastPort+1 {
			lastRange = [2]int{port, port}
			result = append(result, lastRange)
		} else { // 如果是连续的
			lastRange[1] = port
			result[len(result)-1] = lastRange
		}

		lastPort = port
	}

	return result
}
