package audit

import (
	"context"
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
)

func TestRequestCaptureWriteContextDropsUnsafeValuesAfterCancel(t *testing.T) {
	type unsafeKey struct{}

	sourceCtx := context.WithValue(context.Background(), constants.ContextKeyRequestID, "req-123")
	sourceCtx = context.WithValue(sourceCtx, constants.ContextKeyTraceparent, "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
	sourceCtx = context.WithValue(sourceCtx, unsafeKey{}, "request-scoped")
	sourceCtx, cancelSource := context.WithCancel(sourceCtx)
	cancelSource()

	writeCtx, cancel := requestCaptureWriteContext(sourceCtx)
	defer cancel()

	if err := writeCtx.Err(); err != nil {
		t.Fatalf("write context inherited source cancellation: %v", err)
	}
	if _, ok := writeCtx.Deadline(); !ok {
		t.Fatal("write context is missing timeout deadline")
	}
	if got, _ := writeCtx.Value(constants.ContextKeyRequestID).(string); got != "req-123" {
		t.Fatalf("request id = %q, want req-123", got)
	}
	if got, _ := writeCtx.Value(constants.ContextKeyTraceparent).(string); got == "" {
		t.Fatal("traceparent was not preserved")
	}
	if got := writeCtx.Value(unsafeKey{}); got != nil {
		t.Fatalf("unsafe request-scoped value leaked into write context: %#v", got)
	}
}

func TestRequestCaptureWriteContextNilSourceIsBounded(t *testing.T) {
	writeCtx, cancel := requestCaptureWriteContext(nil)
	defer cancel()

	if err := writeCtx.Err(); err != nil {
		t.Fatalf("write context unexpectedly canceled: %v", err)
	}
	if _, ok := writeCtx.Deadline(); !ok {
		t.Fatal("write context is missing timeout deadline")
	}
}

func TestWriteCaptureRowRecoversStorePanic(t *testing.T) {
	defer func() {
		if recovered := recover(); recovered != nil {
			t.Fatalf("request capture write panic escaped: %v", recovered)
		}
	}()

	writeCaptureRow(context.Background(), panicRequestCaptureStore{}, RequestCaptureRow{
		RequestID: "req-123",
		Path:      "/services/data/v63.0/sobjects/Account",
	})
}

type panicRequestCaptureStore struct{}

func (panicRequestCaptureStore) InsertRequestCapture(context.Context, RequestCaptureRow) error {
	panic("request capture store test panic")
}
