package websocket

import (
	"encoding/json"
	"primesys_producer/src/logger"
)

type Hub struct {
	// Registered pools
	clients map[string]*Client

	register chan *Client

	unregister chan *Client

	direct chan directMessage
}

type directMessage struct {
	key  string
	data []byte
}

var socketHub = newHub()

func newHub() *Hub {
	return &Hub{
		clients:    make(map[string]*Client),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		direct:     make(chan directMessage),
	}
}

func (h *Hub) run() {
	for {
		select {
		case client := <-h.register:
			h.clients[client.Key] = client
		case client := <-h.unregister:
			if _, ok := h.clients[client.Key]; ok {
				delete(h.clients, client.Key)
				close(client.send)
			}
		case msg := <-h.direct:
			client, ok := h.clients[msg.key]
			if !ok {
				logger.Info("Key=%s socket client not connected", msg.key)
				continue
			}
			select {
			case client.send <- msg.data:
			default:
				logger.Error("Key=%s socket client send failed", msg.key)
			}
		}
	}
}

// SendToClient sends the device command response only to the socket client of that imei
func SendToClient(response DeviceCommandResponse) {
	data, err := json.Marshal(response)
	if err != nil {
		logger.Error("imei=%d socket response marshal error: %v", response.Imei, err)
		return
	}
	socketHub.direct <- directMessage{key: response.Key, data: data}
}
