/*
提供统一的ip验证的逻辑；包括两部分：
1、ManageCenter中配置到ServerGroup中的IP；系统内部自动处理，外部无需关注(暂时不用)；
2、各个应用程序中配置的ip；通过调用Init或InitString方法进行初始化；
*/
package ipMgr

import (
	"sync"

	"goutil/stringUtil"
)

var (
	ipMap           = make(map[string]struct{}, 32)    // 本地ip集合
	ipCheckFuncList = make([]func(string) bool, 0, 16) // ip检查函数列表
	mutex           sync.RWMutex
)

// 初始化IP列表
func Init(ipList []string) {
	mutex.Lock()
	defer mutex.Unlock()

	// 先清空再初始化
	ipMap = make(map[string]struct{}, 32)
	for _, item := range ipList {
		ipMap[item] = struct{}{}
	}
}

// 初始化ip字符串（以分隔符分割的，分隔符为：",", ";", ":", "|", "||"）
func InitString(ipStr string) {
	mutex.Lock()
	defer mutex.Unlock()

	// 先清空再初始化
	ipMap = make(map[string]struct{}, 32)
	for _, item := range stringUtil.Split(ipStr, nil) {
		ipMap[item] = struct{}{}
	}
}

func AddString(ipStr string) {
	mutex.Lock()
	defer mutex.Unlock()

	// 先清空再初始化
	if ipMap == nil {
		ipMap = make(map[string]struct{}, 32)
	}

	for _, item := range stringUtil.Split(ipStr, nil) {
		ipMap[item] = struct{}{}
	}
}

// RegisterIpCheckFunc 注册Ip检查函数
func RegisterIpCheckFunc(funcName string, funcItem func(string) bool) {
	mutex.Lock()
	defer mutex.Unlock()

	ipCheckFuncList = append(ipCheckFuncList, funcItem)
}

func isLocalValid(ip string) bool {
	mutex.RLock()
	defer mutex.RUnlock()

	_, exist := ipMap[ip]
	return exist
}

func isCheckFuncValid(ip string) bool {
	mutex.RLock()
	defer mutex.RUnlock()

	for _, funcItem := range ipCheckFuncList {
		if funcItem(ip) {
			return true
		}
	}

	return false
}

// 判断传入的Ip是否有效
// ip:ip
// 返回值：
// 是否有效
func IsIpValid(ip string) bool {
	return isLocalValid(ip) || isCheckFuncValid(ip)
}
