package registry

import "errors"

//节点
type Node struct {
	ServiceName string            //服务名称
	Id          string            //节点编号
	Address     string            //地址
	Port        int               //端口
	Meta        map[string]string //元数据
	Status      string            //状态
}

//服务
type Service struct {
	Name    string              //服务名称
	NodeMap map[string]*Node    //节点映射
	TagMap  map[string]struct{} //标签
}

//观察者
type Observer interface {
	//删除服务事件
	DeleteService(serviceName string)

	//更新节点事件
	UpdateNodes(service *Service)

	//添加节点
	AddNode(node *Node)

	//删除节点
	DelNode(node *Node)
}

//注册器
type Registry interface {
	//初始化
	Init(options map[string]interface{}) error

	//服务注册
	Register(node *Node) error

	//服务注销
	Deregister(node *Node) error

	//获取服务映射
	GetServiceMap() map[string]*Service

	//获取服务
	GetService(serviceName string) (*Service, error)

	//设置观察者
	SetObserver(name string, observer Observer) error

	//删除观察者
	DelObserver(name string) error
}

var newRegistryMap = make(map[string]func() Registry, 0)

//新建注册器
func New(name string) Registry {
	if newRegistry, ok := newRegistryMap[name]; ok {
		return newRegistry()
	} else {
		return nil
	}
}

//新建节点
func NewNode(serviceName string, id string, address string, port int) *Node {
	return &Node{
		ServiceName: serviceName,
		Id:          id,
		Address:     address,
		Port:        port,
		Status:      "unknown",
		Meta:        make(map[string]string, 0),
	}
}

//新建服务
func NewService(name string) *Service {
	return &Service{
		Name:    name,
		NodeMap: make(map[string]*Node, 0),
		TagMap:  make(map[string]struct{}, 0),
	}
}

//默认注册器
var defaultRegistry Registry = nil

//初始化
func Init(name string, options map[string]interface{}) error {
	if defaultRegistry != nil {
		return nil
	}

	defaultRegistry = New(name)
	if defaultRegistry == nil {
		return errors.New("new registry error")
	}

	return defaultRegistry.Init(options)
}

//服务注册
func Register(node *Node) error {
	if defaultRegistry == nil {
		return errors.New("default registry is not exists")
	}
	return defaultRegistry.Register(node)
}

//服务注销
func Deregister(node *Node) error {
	if defaultRegistry == nil {
		return errors.New("default registry is not exists")
	}
	return defaultRegistry.Deregister(node)
}

//获取服务映射
func GetServiceMap() map[string]*Service {
	if defaultRegistry == nil {
		return make(map[string]*Service, 0)
	}
	return defaultRegistry.GetServiceMap()
}

//获取服务
func GetService(serviceName string) (*Service, error) {
	if defaultRegistry == nil {
		return nil, errors.New("default registry is not exists")
	}
	return defaultRegistry.GetService(serviceName)
}

//设置观察者
func SetObserver(name string, observer Observer) error {
	if defaultRegistry == nil {
		return errors.New("default registry is not exists")
	}
	return defaultRegistry.SetObserver(name, observer)
}

//删除观察者
func DelObserver(name string) error {
	if defaultRegistry == nil {
		return errors.New("default registry is not exists")
	}
	return defaultRegistry.DelObserver(name)
}
