package redis_test

import (
	"context"
	"encoding/json"
	"io"
	"log/slog"
	"testing"

	miniredis "github.com/alicebob/miniredis/v2"

	"bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/config"
	contractevents "bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/contracts/events"
	redisclient "bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/redis"
)

func TestPublisher_CommitAnalysisReady(t *testing.T) {
	server, err := miniredis.Run()
	if err != nil {
		t.Fatalf("start miniredis: %v", err)
	}
	defer server.Close()

	cfg := config.RedisConfig{URL: "redis://" + server.Addr()}
	client, err := redisclient.New(cfg)
	if err != nil {
		t.Fatalf("new client: %v", err)
	}
	defer client.Close()

	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
	publisher := redisclient.NewPublisher(client, cfg, logger)

	event := contractevents.NewCommitAnalysisReadyEvent(
		"evt_out_01",
		"ad/example",
		"target4567890ab",
		"analysis_ad_example_abc",
	)
	event.ImpactedSymbols = []string{"Run"}
	event.ChangedFiles = []string{"main.go"}
	event.Summary = "1 files changed"
	event.GraphSchemaVersion = "v1"

	ctx := context.Background()
	if err := publisher.PublishCommitAnalysisReady(ctx, event); err != nil {
		t.Fatalf("publish: %v", err)
	}

	stream := cfg.StreamName(contractevents.StreamCommitAnalysisReady)
	msgs, err := client.Underlying().XRange(ctx, stream, "-", "+").Result()
	if err != nil {
		t.Fatalf("xrange: %v", err)
	}
	if len(msgs) != 1 {
		t.Fatalf("expected 1 stream entry, got %d", len(msgs))
	}

	payload, ok := msgs[0].Values["payload"].(string)
	if !ok {
		t.Fatal("expected string payload")
	}
	var decoded contractevents.CommitAnalysisReadyEvent
	if err := json.Unmarshal([]byte(payload), &decoded); err != nil {
		t.Fatalf("unmarshal published payload: %v", err)
	}
	if decoded.AnalysisID != event.AnalysisID {
		t.Fatalf("analysis_id: got %q want %q", decoded.AnalysisID, event.AnalysisID)
	}
}
