// package serv_bots -- словарь ботов сервера
package serv_bots

import (
	"encoding/json"
	"fmt"
	"log"
	"sync"

	"wartank/pkg/types"
	"wartank/server/serv_bots/warbot"
)

// ServBots -- словарь ботов на сервере
type ServBots struct {
	server types.IServer
	store  types.IStore
	dict   map[string]types.IServBot
	block  sync.RWMutex
}

// NewServBots -- возвращает новый словарь серверных ботов
func NewServBots(server types.IServer) (*ServBots, error) {
	if server == nil {
		return nil, fmt.Errorf("NewServBots(): IServer == nil")
	}
	sf := &ServBots{
		server: server,
		store:  server.Store(),
		dict:   make(map[string]types.IServBot),
	}
	return sf, nil
}

// Get -- возвращает боевого бота по имени
func (sf *ServBots) Get(name string) types.IServBot {
	sf.block.RLock()
	defer sf.block.RUnlock()
	bot, isOk := sf.dict[name]
	if !isOk {
		return nil
	}
	return bot
}

// Загружает ботов из хранилища
func (sf *ServBots) Load() error {
	sf.block.Lock()
	defer sf.block.Unlock()
	log.Println("ServBots.load()")
	mapRes, err := sf.store.Find("/bots/list")
	if err != nil {
		return fmt.Errorf("ServBots.load(): in get list bot, err=\n\t%w", err)
	}
	strList := mapRes["/bots/list"]
	lstBot := make([]string, 0)
	if strList != "" { // Такое может быть при первом запуске
		err = json.Unmarshal([]byte(strList), &lstBot)
		if err != nil {
			return fmt.Errorf("ServBots.load(): in unmarshal list bot, err=\n\t%w", err)
		}
	}

	for _, name := range lstBot {
		bot, err := warbot.NewWarBot(sf.server, name)
		if err != nil {
			return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", name, err)
		}
		go bot.Run()
		sf.dict[name] = bot
	}
	return nil
}

// BotStart -- запускает бота в работу по его имени
func (sf *ServBots) BotStart(name string) error {
	bot := sf.dict[name]
	if bot == nil {
		return fmt.Errorf("ServBots.BotStart(): bot(%v) not found", name)
	}
	err := bot.Run()
	if err != nil {
		return fmt.Errorf("ServBots.BotStart(): in run bot(%v), err=\n\t%w", name, err)
	}
	return nil
}
