package httpapi

import (
	"context"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/identity"
	"github.com/easyai/easyai-ai-gateway/apps/api/internal/identityruntime"
	"github.com/easyai/easyai-ai-gateway/apps/api/internal/securityevents"
)

type preparedReceiverBuilder struct {
	receiver http.Handler
}

func (builder *preparedReceiverBuilder) Build(context.Context, identity.Revision) (*identityruntime.Runtime, error) {
	return &identityruntime.Runtime{}, nil
}

func (builder *preparedReceiverBuilder) PreparedSecurityEventReceiver() http.Handler {
	return builder.receiver
}

func TestReceiveSecurityEventUsesPreparedReceiverBeforeFirstActivation(t *testing.T) {
	called := false
	builder := &preparedReceiverBuilder{receiver: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		called = true
		w.WriteHeader(http.StatusAccepted)
	})}
	server := &Server{identityRuntime: identityruntime.NewManager(nil, builder)}
	request := httptest.NewRequest(http.MethodPost, "/api/v1/security-events/ssf", nil)
	response := httptest.NewRecorder()

	server.receiveSecurityEvent(response, request)

	if !called || response.Code != http.StatusAccepted {
		t.Fatalf("prepared SSF receiver called=%t status=%d", called, response.Code)
	}
}

func TestReceiveSecurityEventReturnsNotFoundWithoutConfiguredReceiver(t *testing.T) {
	server := &Server{identityRuntime: identityruntime.NewManager(nil, &preparedReceiverBuilder{})}
	request := httptest.NewRequest(http.MethodPost, "/api/v1/security-events/ssf", nil)
	response := httptest.NewRecorder()

	server.receiveSecurityEvent(response, request)

	if response.Code != http.StatusNotFound {
		t.Fatalf("unconfigured SSF status=%d, want %d", response.Code, http.StatusNotFound)
	}
}

func TestSecurityEventWriteAuditFailsClosedBeforeMutation(t *testing.T) {
	server := &Server{}
	request := httptest.NewRequest(http.MethodPost, "/api/admin/system/security-events/connection/verify", nil)
	recorder := httptest.NewRecorder()

	if _, ok := server.requireSecurityEventConnectionAudit(
		recorder, request, "verify", "trace-test", securityevents.ConnectionView{},
	); ok {
		t.Fatal("security event write unexpectedly continued without durable audit storage")
	}
	if recorder.Code != http.StatusServiceUnavailable {
		t.Fatalf("audit failure status=%d, want 503", recorder.Code)
	}
}
