package discovery

import (
	"encoding/json"

	"github.com/tech/sendico/pkg/merrors"
	messaging "github.com/tech/sendico/pkg/messaging/envelope"
	"github.com/tech/sendico/pkg/model"
)

type jsonEnvelope struct {
	messaging.Envelope
	payload any
}

func (e *jsonEnvelope) Serialize() ([]byte, error) {
	if e.payload == nil {
		return nil, merrors.InvalidArgument("discovery envelope payload is nil")
	}
	data, err := json.Marshal(e.payload)
	if err != nil {
		return nil, err
	}
	return e.Wrap(data)
}

func newEnvelope(sender string, event model.NotificationEvent, payload any) messaging.Envelope {
	return &jsonEnvelope{
		Envelope: messaging.CreateEnvelope(sender, event),
		payload:  payload,
	}
}

func NewServiceAnnounceEnvelope(sender string, payload Announcement) messaging.Envelope {
	return newEnvelope(sender, ServiceAnnounceEvent(), payload)
}

func NewGatewayAnnounceEnvelope(sender string, payload Announcement) messaging.Envelope {
	return newEnvelope(sender, GatewayAnnounceEvent(), payload)
}

func NewHeartbeatEnvelope(sender string, payload Heartbeat) messaging.Envelope {
	return newEnvelope(sender, HeartbeatEvent(), payload)
}

func NewLookupRequestEnvelope(sender string, payload LookupRequest) messaging.Envelope {
	return newEnvelope(sender, LookupRequestEvent(), payload)
}

func NewLookupResponseEnvelope(sender string, payload LookupResponse) messaging.Envelope {
	return newEnvelope(sender, LookupResponseEvent(), payload)
}

func NewRefreshUIEnvelope(sender string, payload RefreshEvent) messaging.Envelope {
	return newEnvelope(sender, RefreshUIEvent(), payload)
}
