package server

import (
	"fmt"
	"game/common/gameService"
	"game/common/proto/pb"
	"game/common/serviceName"
	"game/server/lobby/config"
	"github.com/fox/fox/ipb"
	"github.com/fox/fox/log"
	"github.com/fox/fox/service"
	"github.com/golang/protobuf/proto"
)

// 大厅服-无状态服，自身不持有任何状态包括玩家数据
var lobby []*LobbyService

type LobbyService struct {
	*gameService.GameService
}

func Init() {
	for i := 0; i < config.Command.ServiceNum; i++ {
		sid := config.Command.ServiceId + i
		if srv := newLobbyService(sid); srv != nil {
			lobby = append(lobby, srv)
		}
	}
}

func Stop() {
	for _, srv := range lobby {
		srv.NotifyStop()
	}
	for _, srv := range lobby {
		srv.WaitStop()
	}
}

func newLobbyService(serviceId int) *LobbyService {
	s := new(LobbyService)

	sName := fmt.Sprintf("%v-%d", serviceName.Lobby, serviceId)
	s.GameService = gameService.NewGameService(&service.InitNatsServiceParams{
		EtcdAddress:  config.Cfg.Etcd.Address,
		EtcdUsername: "",
		EtcdPassword: "",
		NatsAddress:  config.Cfg.Nats.Address,
		ServiceType:  serviceName.Lobby,
		ServiceName:  sName,
		OnFunc:       s,
		TypeId:       int(pb.ServiceTypeId_STI_Lobby),
		Version:      config.Cfg.BuildDate,
	}, &config.Cfg.Redis)

	s.initProcessor()
	s.OnInit()
	return s
}

func (s *LobbyService) OnInit() {
	if err := s.NatsService.QueueSubscribe(service.GroupTopic(s), service.GroupQueue(s)); err != nil {
		log.Error(err.Error())
	}
	s.NatsService.Run()
	log.Debug("onInit")
}

func (s *LobbyService) CanStop() bool {
	//log.Debug("chatService.CanStop")
	return true
}

func (s *LobbyService) OnStop() {
	s.NatsService.OnStop()
	log.Debug("OnStop")
}

// 处理其它服发送过来的消息
func (s *LobbyService) OnMessage(data []byte) error {
	var iMsg = &ipb.InternalMsg{}
	var err error
	if err = proto.Unmarshal(data, iMsg); err != nil {
		log.Error(err.Error())
		return err
	}
	if req, err := s.Processor().Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil {
		err = s.Processor().Dispatch(iMsg.MsgId, iMsg, req)
	} else {
		log.Error(err.Error())
	}
	//log.Debug(s.Log("received message:%v", iMsg.MsgId))
	return nil
}
