package geo

import (
	"context"
	"database/sql"
	"errors"
	"testing"

	"github.com/google/uuid"
	"go.uber.org/zap"
)

// NewServiceForTest builds a Service with no GeoLite2 resolver. It is
// the entry point external tests use when they want to exercise the
// counter / admin paths without spinning up a real mmdb file. The
// returned Service still owns its background context and logger so
// IncrementCounterAsync and ListUserCounters behave exactly as they do
// in production.
func NewServiceForTest(db *sql.DB) (*Service, error) {
	if db == nil {
		return nil, errors.New("geo: db must not be nil")
	}
	bgCtx, bgCancel := context.WithCancel(context.Background())
	return &Service{
		db:       db,
		logger:   zap.NewNop(),
		bgCtx:    bgCtx,
		bgCancel: bgCancel,
	}, nil
}

// IncrementCounterTestSync runs the package-private upsert path
// synchronously so external tests can assert on counter rows without
// having to deal with goroutine scheduling. Failure to upsert fails the
// test rather than being silently logged.
func (s *Service) IncrementCounterTestSync(t *testing.T, userID uuid.UUID, country string) {
	t.Helper()
	ctx, cancel := context.WithTimeout(context.Background(), counterUpsertTimeout)
	defer cancel()
	if err := s.upsertCounter(ctx, userID, country); err != nil {
		t.Fatalf("upsert counter (%s/%s): %v", userID, country, err)
	}
}
