package auth

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

func TestServerMainAPIKeyUsesSignedCurrentContract(t *testing.T) {
	const key = "gateway-test"
	const secret = "server-main-internal-secret"
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
		if request.URL.Path != "/internal/auth/verify-apikey" || request.Header.Get("X-Internal-Key") != key {
			t.Fatalf("unexpected request %s", request.URL.Path)
		}
		body, _ := io.ReadAll(request.Body)
		hash := sha256.Sum256(body)
		text := strings.Join([]string{
			request.Method, request.URL.RequestURI(), request.Header.Get("X-Timestamp"), request.Header.Get("X-Nonce"),
			hex.EncodeToString(hash[:]), key,
		}, "\n")
		mac := hmac.New(sha256.New, []byte(secret))
		_, _ = mac.Write([]byte(text))
		if !hmac.Equal([]byte(request.Header.Get("X-Signature")), []byte(hex.EncodeToString(mac.Sum(nil)))) {
			t.Fatal("invalid internal request signature")
		}
		_ = json.NewEncoder(w).Encode(map[string]any{"success": true, "data": map[string]any{"user": map[string]any{
			"sub": "server-user", "username": "server", "role": []string{"user"}, "tenantId": "server-tenant",
		}}})
	}))
	t.Cleanup(server.Close)
	authenticator := New("jwt", server.URL, "")
	authenticator.ServerMainInternalKey = key
	authenticator.ServerMainInternalSecret = secret
	request := httptest.NewRequest(http.MethodGet, "/api/v1/me", nil)
	request.Header.Set("Authorization", "Bearer sk-server-main")
	user, err := authenticator.Authenticate(request)
	if err != nil {
		t.Fatal(err)
	}
	if user.ID != "server-user" || user.Source != "server-main" || user.TenantID != "server-tenant" {
		t.Fatalf("user = %#v", user)
	}
}
