// Package balance...
//
// Description : balance...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-22 4:39 下午
package balance

import (
	"net/http"
	"sync"

	"git.zhangdeman.cn/zhangdeman/gopkg/util"

	"github.com/pkg/errors"

	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
)

// NewIPHash ip hash 负载均衡
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:53 下午 2021/11/22
func NewIPHash(severList []*define.ServerNode) (IBalance, error) {
	if nil == severList || len(severList) == 0 {
		return nil, errors.New("sever list is empty")
	}
	return &IPHash{
		base: base{
			lock:      &sync.RWMutex{},
			severList: severList,
		},
		serverList: severList,
	}, nil
}

// IPHash ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:57 下午 2021/11/22
type IPHash struct {
	base
	serverList []*define.ServerNode
}

// GetServerNode ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:53 下午 2021/11/22
func (ih *IPHash) GetServerNode(req *http.Request) (*define.ServerNode, error) {
	clintIPHashID := util.GetHashID(util.GetRemoteIp(req))
	ih.RLock()
	defer ih.RUnlock()
	if len(ih.serverList) == 0 {
		return nil, errors.New("sever list is empty")
	}
	return ih.serverList[int(clintIPHashID%uint64(len(ih.serverList)))], nil
}