package mq

import (
	"context"
	"testing"

	platformmq "kra/pkg/mq"
)

type fakeClient struct {
	subscribed   []string
	unsubscribed []string
}

func (*fakeClient) Publish(context.Context, string, []byte, byte, bool) error { return nil }
func (f *fakeClient) Subscribe(_ context.Context, topic string, _ byte, _ platformmq.Handler) error {
	f.subscribed = append(f.subscribed, topic)
	return nil
}
func (f *fakeClient) Unsubscribe(_ context.Context, topics ...string) error {
	f.unsubscribed = append(f.unsubscribed, topics...)
	return nil
}
func (*fakeClient) Connected() bool { return true }
func (*fakeClient) Close() error    { return nil }

func TestReloadableTracksSubscriptions(t *testing.T) {
	client := &fakeClient{}
	r := &Reloadable{
		clients:       map[string]platformmq.Client{ProviderEMQX: client},
		subscriptions: make(map[string]map[string]subscription),
	}
	handler := func(context.Context, platformmq.Message) {}
	if err := r.Subscribe(context.Background(), "orders/+/paid", platformmq.AtLeastOnce, handler); err != nil {
		t.Fatal(err)
	}
	if _, ok := r.subscriptions[ProviderEMQX]["orders/+/paid"]; !ok {
		t.Fatal("subscription was not retained for configuration reload")
	}
	if err := r.Unsubscribe(context.Background(), "orders/+/paid"); err != nil {
		t.Fatal(err)
	}
	if _, ok := r.subscriptions[ProviderEMQX]["orders/+/paid"]; ok {
		t.Fatal("unsubscribed topic remained in the reload registry")
	}
}

func TestReloadableRestoresSubscriptions(t *testing.T) {
	client := &fakeClient{}
	r := &Reloadable{subscriptions: map[string]map[string]subscription{
		ProviderEMQX: {
			"orders/+/paid": {qos: platformmq.AtLeastOnce, handler: func(context.Context, platformmq.Message) {}},
		},
	}}
	if err := r.restoreSubscriptionsLocked(ProviderEMQX, client); err != nil {
		t.Fatal(err)
	}
	if len(client.subscribed) != 1 || client.subscribed[0] != "orders/+/paid" {
		t.Fatalf("restored subscriptions = %v", client.subscribed)
	}
}
