/*
@Time : 2020/9/7 19:51
@Author : xuhanlin
@File : Service.go
@Description : 服务管理器
*/

package service

import (
	log "Server-Core/Server/Base/Log"
	"errors"
	"sync"
)

var m *mgr

type context struct {
	name string
	args []interface{}
	ch   chan Msg
	h    Handler
}

type mgr struct {
	serviceByName map[string]*context
	wg            sync.WaitGroup
}

func Init() error {
	m = new(mgr)
	m.serviceByName = make(map[string]*context)
	return nil
}

func UnInit() {
	for _, v := range m.serviceByName {
		v.h.UnInit()
		close(v.ch)
	}

	m.wg.Wait()
	m.serviceByName = make(map[string]*context)
}

func Run() {
	for _, v := range m.serviceByName {
		if v.h.Status() == false {
			log.Warn("重启服务 name:%s", v.name)
			v.h.Init(v.ch, &m.wg, v.args...)
			go v.h.Run()
			m.wg.Add(1)
		}
	}
}

func Register(name string, h Handler, args ...interface{}) error {
	_, ok := m.serviceByName[name]
	if ok {
		return errors.New("服务已注册: " + name)
	}

	c := new(context)
	c.name = name
	c.ch = make(chan Msg, 1000)
	c.h = h
	c.args = args
	err := h.Init(c.ch, &m.wg, c.args...)
	if err != nil {
		return err
	}
	go h.Run()
	m.serviceByName[name] = c
	m.wg.Add(1)
	return nil
}

func Send(name string, cmd string, args ...interface{}) {
	c, ok := m.serviceByName[name]
	if !ok {
		log.Warn("服务未注册name:%s", c.name)
	}

	var msg Msg
	msg.Cmd = cmd
	msg.Args = args
	c.ch <- msg
	if len(c.ch) > int(float64(cap(c.ch))*0.8) {
		log.Warn("服务负载过高name:%s,total:%d,cur:%d")
	}
}

func Call(name string, cmd string, args ...interface{}) ([]interface{}, error) {
	c, ok := m.serviceByName[name]
	if !ok {
		return []interface{}{}, errors.New("服务未注册: " + name)
	}

	done := make(chan []interface{})
	var msg Msg
	msg.Cmd = cmd
	msg.Args = args
	msg.Sync = true
	msg.Done = done
	c.ch <- msg
	if len(c.ch) > int(float64(cap(c.ch))*0.8) {
		log.Warn("服务负载过高name:%s,total:%d,cur:%d")
	}

	ret := <-done
	close(msg.Done)
	return ret, nil
}
