//go:build integration

// Package testutil provides shared helpers for integration tests, which run
// against the compose Mongo (published on 127.0.0.1 by
// docker-compose.test.yml) using a per-run database name that is dropped on
// cleanup.
package testutil

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"

	"go.mongodb.org/mongo-driver/v2/mongo"
	"go.mongodb.org/mongo-driver/v2/mongo/options"
	"go.mongodb.org/mongo-driver/v2/mongo/readpref"

	"bountyboard/internal/ulid"
)

// MongoDB connects to the test Mongo (MONGO_TEST_URI, default localhost) and
// returns a database with a unique per-run name, dropped automatically.
func MongoDB(t *testing.T) *mongo.Database {
	t.Helper()
	uri := os.Getenv("MONGO_TEST_URI")
	if uri == "" {
		uri = "mongodb://127.0.0.1:27017"
	}
	client, err := mongo.Connect(options.Client().
		ApplyURI(uri).
		SetServerSelectionTimeout(5 * time.Second))
	if err != nil {
		t.Fatalf("mongo connect: %v", err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := client.Ping(ctx, readpref.Primary()); err != nil {
		t.Fatalf("mongo at %s not reachable (start it with: docker compose -f docker-compose.yml -f docker-compose.test.yml up -d mongo): %v", uri, err)
	}

	db := client.Database("bountyboard_test_" + strings.ToLower(ulid.New()))
	t.Cleanup(func() {
		ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
		defer cancel()
		if err := db.Drop(ctx); err != nil {
			t.Errorf("drop test db: %v", err)
		}
		_ = client.Disconnect(ctx)
	})
	return db
}
