package rpcsrv

import (
	"sync/atomic"

	"github.com/gorilla/websocket"
	"git.marketally.com/tutus-one/tutus-chain/pkg/tutusrpc"
)

type (
	// intEvent is an internal event that has both a proper structure and
	// a websocket-ready message. It's used to serve websocket-based clients
	// as well as internal ones.
	intEvent struct {
		msg *websocket.PreparedMessage
		ntf *tutusrpc.Notification
	}
	// subscriber is an event subscriber.
	subscriber struct {
		writer    chan<- intEvent
		overflown atomic.Bool
		// These work like slots as there is not a lot of them (it's
		// cheaper doing it this way rather than creating a map),
		// pointing to an EventID is an obvious overkill at the moment, but
		// that's not for long.
		feeds []feed
	}
	// feed stores subscriber's desired event ID with filter.
	feed struct {
		event  tutusrpc.EventID
		filter tutusrpc.SubscriptionFilter
	}
)

// EventID implements tutusrpc.EventComparator interface and returns notification ID.
func (f feed) EventID() tutusrpc.EventID {
	return f.event
}

// Filter implements tutusrpc.EventComparator interface and returns notification filter.
func (f feed) Filter() tutusrpc.SubscriptionFilter {
	return f.filter
}

const (
	// The default maximum number of subscriptions per one client.
	defaultMaxFeeds = 16

	// This sets notification messages buffer depth. It may seem to be quite
	// big, but there is a big gap in speed between internal event processing
	// and networking communication that is combined with spiky nature of our
	// event generation process, which leads to lots of events generated in
	// a short time and they will put some pressure to this buffer (consider
	// ~500 invocation txs in one block with some notifications). At the same
	// time, this channel is about sending pointers, so it's doesn't cost
	// a lot in terms of memory used.
	notificationBufSize = 1024
)
