/**
 * @Author: toad
 * @Data: 2020/9/5 下午2:27
 */
package tpro

import (
	"net"
	"regexp"
	"strings"
)

var (
	ipRegexp, _ = regexp.Compile("([0-9]*.[0-9]*.[0-9]*.[0-9]*:[0-9]*)->([0-9]*.[0-9]*.[0-9]*.[0-9]*:[0-9]*)")
	// 阿里slb CIDR地址
	aliyunSLB = []string{"100.64.0.0/10", "10.158.0.0/16", "10.159.0.0/16", "10.49.0.0/16"}
)

type ResetAddr struct {
	Source string
	Dest   string
}

// IsResetErr 判断是否是tcp reset包导致的错误
func IsResetErr(err error) (resetAddr ResetAddr, flag bool) {
	if err == nil {
		return resetAddr, false
	}
	str := err.Error()
	// todo  优化
	if !strings.Contains(str, "connection reset by peer") {
		return resetAddr, false
	}
	if ipRegexp == nil {
		return resetAddr, false
	}
	addrList := strings.Split(ipRegexp.FindString(str), "->")
	if len(addrList) < 2 {
		return resetAddr, true
	}
	sourceIps := strings.Split(addrList[0], ":")
	if len(sourceIps) <= 0 {
		resetAddr.Source = addrList[0]
	} else {
		resetAddr.Source = sourceIps[0]
	}
	destIps := strings.Split(addrList[1], ":")
	if len(sourceIps) <= 0 {
		resetAddr.Dest = addrList[1]
	} else {
		resetAddr.Dest = destIps[0]
	}
	return resetAddr, true
}

func GetAliyunSLBCIDR() []*net.IPNet {
	result, _ := ParseCIDR(aliyunSLB)
	return result
}

// ParseCIDR 解析CIDR的地址,返回对应的网络段和掩码
func ParseCIDR(cidrAddrList []string) ([]*net.IPNet, error) {
	result := make([]*net.IPNet, len(cidrAddrList))
	for index, cidrAddr := range cidrAddrList {
		_, ipNet, err := net.ParseCIDR(cidrAddr)
		if err != nil {
			return make([]*net.IPNet, 0), err // 怂，有地方忽略error直接使用还是默认返回一个切片吧
		}
		result[index] = ipNet
	}
	return result, nil
}
