// package cleint_proxy -- прокси подписывания клиента на топики по шаблону
package cleint_proxy

import (
	"fmt"
	"log"
	"sync"
	"time"

	"p78git.ddns.net/svi/gobus/pkg/alias"
	"p78git.ddns.net/svi/gobus/pkg/net/netapi"
	"p78git.ddns.net/svi/gobus/pkg/types"
)

// ClientProxy -- параметры подписывания клиента на топик
type ClientProxy struct {
	name   alias.ClientName      // Имя клиента
	sample alias.TopicName       // Образец подписи
	isWork bool                  // Признак, что получатель живой
	chMsg  chan *netapi.TopicMsg // Канал для обратной связи из топиков
	block  sync.RWMutex
}

// NewClientProxy -- возвращает новый прокси подписывания клиента на топик
func NewClientProxy(name alias.ClientName, sample alias.TopicName) (*ClientProxy, error) {
	log.Printf("NewClientProxy(): name=%q, sample=%q\n", name, sample)
	if name == "" {
		return nil, fmt.Errorf("NewClientProxy(): name is empty")
	}
	suffix := "_" + alias.ClientName(fmt.Sprint(time.Now().UnixMilli()))
	sf := &ClientProxy{
		name:   name + suffix,
		sample: sample,
		chMsg:  make(chan *netapi.TopicMsg, 10),
		isWork: true,
	}
	_ = types.IClientProxy(sf)
	return sf, nil
}

// ResetWork -- сбрасывает признак работы
func (sf *ClientProxy) ResetWork() {
	sf.block.Lock()
	defer sf.block.Unlock()
	sf.isWork = false
	close(sf.chMsg)
}

// IsWork -- возвращает признак работы прокси
func (sf *ClientProxy) IsWork() bool {
	sf.block.RLock()
	defer sf.block.RUnlock()
	return sf.isWork
}

// Read -- читает канал сообщений от топиков
func (sf *ClientProxy) Read() *netapi.TopicMsg {
	msg := <-sf.chMsg
	return msg
}

// Write -- записывает в себя сообщение топика
func (sf *ClientProxy) Write(msg *netapi.TopicMsg) {
	sf.block.Lock()
	defer sf.block.Unlock()
	if !sf.isWork {
		return
	}
	sf.chMsg <- msg
}

// SampleTopic -- возвращает образец шаблона подписки на топики
func (sf *ClientProxy) SampleTopic() alias.TopicName {
	return sf.sample
}

// ClientName -- возвращает имя клиента
func (sf *ClientProxy) ClientName() alias.ClientName {
	return sf.name
}
