package sfcrmappservice

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"sync/atomic"
	"testing"
	"time"

	apihostmiddleware "github.com/pingcap-inc/nexuscrm-api-host/middleware"
	"github.com/pingcap-inc/nexuscrm-api-host/runtimegrpc"
	authorizationsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/authorizationv1"
	effectivepermissionssemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/effectivepermissionsv1"
	federatedloginsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/federatedloginv1"
	querysemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/queryv1"
	sessionsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/sessionv1"
)

const (
	sessionTestProof        = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
	federatedLoginTestState = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
)

func sessionTestResponse() sessionsemantic.Session {
	return sessionsemantic.Session{
		Principal: sessionsemantic.Principal{
			PrincipalID: "user-1", DisplayName: "Test User", Email: "user@example.test",
			ProfileID: "profile-1", RoleID: "role-1",
		},
		ExpiresAtUnixSecond: time.Now().Add(time.Hour).Unix(),
	}
}

func sessionTestConfig() SessionHTTPConfig {
	return SessionHTTPConfig{
		RuntimeCreateSession: func(context.Context, runtimegrpc.SessionCreateCredentials, sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
			return sessionsemantic.CreateResponse{Session: sessionTestResponse(), AccessTokenIssued: true}, runtimegrpc.SessionIssuedCredentials{AccessToken: "access-token"}, nil
		},
		RuntimeReadSession: func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
			return sessionsemantic.ReadResponse{Session: sessionTestResponse()}, runtimegrpc.SessionIssuedCredentials{}, nil
		},
		RuntimeRevokeSession: func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
			return nil
		},
		RuntimeBeginAuthorization: func(context.Context, authorizationsemantic.BeginRequest) (authorizationsemantic.BeginResponse, error) {
			return authorizationsemantic.BeginResponse{RequestHandle: "authorize-handle", ExpiresAtUnixSecond: time.Now().Add(time.Minute).Unix()}, nil
		},
		RuntimeCompleteAuthorization: func(context.Context, runtimegrpc.SessionPresentedCredentials, authorizationsemantic.CompleteRequest) (authorizationsemantic.CompleteResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
			return authorizationsemantic.CompleteResponse{AuthorizationCodeIssued: true, RedirectURI: "https://client.example.test/callback", State: "state-1"}, runtimegrpc.IssuedAuthorizationCredentials{AuthorizationCode: "authorization-code"}, nil
		},
		RuntimeExchangeAuthorization: func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
			return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "access-token"}, nil
		},
		RuntimeBeginFederatedLogin: func(context.Context, federatedloginsemantic.BeginRequest) (federatedloginsemantic.BeginResponse, error) {
			return federatedloginsemantic.BeginResponse{
				State: federatedLoginTestState, ExpiresAtUnixSecond: time.Now().Add(time.Minute).Unix(),
			}, nil
		},
		RuntimeConsumeFederatedLogin: func(context.Context, federatedloginsemantic.ConsumeRequest) error {
			return nil
		},
		RuntimeReadEffective: func(context.Context, string, effectivepermissionssemantic.Request) (effectivepermissionssemantic.Response, error) {
			return effectivepermissionssemantic.Response{}, nil
		},
		PublicOrigin: "https://crm.example.test", OrganizationID: "org-1",
		PasswordGrantEnabled: true,
	}
}

func TestPublicAuthorizationRoutesProjectOnlyL1WireSemantics(t *testing.T) {
	tests := []struct {
		name         string
		result       authorizationsemantic.BeginResponse
		wantStatus   int
		wantLocation string
		wantBody     string
	}{
		{name: "valid", result: authorizationsemantic.BeginResponse{RequestHandle: "handle-1", ExpiresAtUnixSecond: time.Now().Add(time.Minute).Unix()},
			wantStatus: http.StatusFound, wantLocation: "/login?continue=handle-1"},
		{name: "invalid scope uses verified redirect", result: authorizationsemantic.BeginResponse{ProtocolError: &authorizationsemantic.ProtocolError{
			Code: "invalid_scope", SafeDescription: "scope is not allowed",
			TrustedRedirectURI: "https://client.example/callback", State: "state-1"}},
			wantStatus: http.StatusFound, wantLocation: "https://client.example/callback?error=invalid_scope&error_description=scope+is+not+allowed&state=state-1"},
		{name: "unknown client never redirects", result: authorizationsemantic.BeginResponse{ProtocolError: &authorizationsemantic.ProtocolError{
			Code: "invalid_client", SafeDescription: "invalid client"}},
			wantStatus: http.StatusBadRequest, wantBody: `"error":"invalid_client"`},
		{name: "unregistered redirect never redirects", result: authorizationsemantic.BeginResponse{ProtocolError: &authorizationsemantic.ProtocolError{
			Code: "invalid_request", SafeDescription: "redirect is not registered"}},
			wantStatus: http.StatusBadRequest, wantBody: `"error":"invalid_request"`},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			config := sessionTestConfig()
			config.RuntimeBeginAuthorization = func(_ context.Context, request authorizationsemantic.BeginRequest) (authorizationsemantic.BeginResponse, error) {
				if request.Issuer != "https://crm.example.test" || request.ClientID != "public-client" ||
					request.RedirectURI != "https://client.example/callback" || request.CodeChallengeMethod != "S256" {
					t.Fatalf("Runtime request=%#v", request)
				}
				return test.result, nil
			}
			session, err := newSessionHTTP(config)
			if err != nil {
				t.Fatal(err)
			}
			request := httptest.NewRequest(http.MethodGet,
				"https://crm.example.test"+AuthorizePath+"?client_id=public-client&redirect_uri=https%3A%2F%2Fclient.example%2Fcallback&response_type=code&scope=api&state=state-1&code_challenge=challenge&code_challenge_method=S256", nil)
			response := httptest.NewRecorder()
			session.serve(response, request)
			if response.Code != test.wantStatus || response.Header().Get("Location") != test.wantLocation ||
				(test.wantBody != "" && !strings.Contains(response.Body.String(), test.wantBody)) {
				t.Fatalf("status=%d location=%q body=%s", response.Code, response.Header().Get("Location"), response.Body.String())
			}
		})
	}
}

func TestPublicAuthorizationResumeAndExchangeKeepSecretsOutOfSemanticPayload(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeCompleteAuthorization = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, request authorizationsemantic.CompleteRequest) (authorizationsemantic.CompleteResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		if credentials.AccessToken != "browser-token" || request.RequestHandle != "handle-1" {
			t.Fatalf("complete credentials=%#v request=%#v", credentials, request)
		}
		return authorizationsemantic.CompleteResponse{AuthorizationCodeIssued: true, RedirectURI: "https://client.example/callback", State: "state-1"}, runtimegrpc.IssuedAuthorizationCredentials{AuthorizationCode: "code-1"}, nil
	}
	config.RuntimeExchangeAuthorization = func(_ context.Context, credentials runtimegrpc.AuthorizationExchangeCredentials, request authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		if credentials.AuthorizationCode != "code-1" || credentials.CodeVerifier != "verifier" || credentials.ClientSecret != "client-secret" ||
			request.GrantType != authorizationsemantic.GrantTypeAuthorizationCode || request.Issuer != "https://crm.example.test" {
			t.Fatalf("exchange credentials=%#v request=%#v", credentials, request)
		}
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{TokenType: "Bearer", ExpiresInSecond: 3600,
				Scope: "api", AccessTokenIssued: true, RefreshTokenIssued: true}},
			runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "access-token", RefreshToken: "refresh-token"}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}

	for _, wire := range []struct {
		name, contentType, body string
	}{
		// Keep the primary case identical to the checked-in frontend consumer. A
		// form-only handler previously passed backend tests while every browser
		// resume failed before reaching Runtime.
		{name: "frontend JSON", contentType: "application/json", body: `{"continue":"handle-1"}`},
		{name: "existing form caller", contentType: "application/x-www-form-urlencoded", body: "continue=handle-1"},
	} {
		t.Run(wire.name, func(t *testing.T) {
			resumeRequest := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+AuthorizeResumePath, strings.NewReader(wire.body))
			resumeRequest.Header.Set("Content-Type", wire.contentType)
			resumeRequest.Header.Set("Authorization", "Bearer browser-token")
			resume := httptest.NewRecorder()
			session.serve(resume, resumeRequest)
			if resume.Code != http.StatusOK || !strings.Contains(resume.Body.String(), "code=code-1") {
				t.Fatalf("resume status=%d body=%s", resume.Code, resume.Body.String())
			}
		})
	}

	exchangeForm := url.Values{"grant_type": {"authorization_code"}, "client_id": {"public-client"}, "client_secret": {"client-secret"},
		"code": {"code-1"}, "code_verifier": {"verifier"}, "redirect_uri": {"https://client.example/callback"}}
	exchangeRequest := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(exchangeForm.Encode()))
	exchangeRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	exchange := httptest.NewRecorder()
	session.serve(exchange, exchangeRequest)
	if exchange.Code != http.StatusOK || !strings.Contains(exchange.Body.String(), `"access_token":"access-token"`) ||
		!strings.Contains(exchange.Body.String(), `"refresh_token":"refresh-token"`) {
		t.Fatalf("exchange status=%d body=%s", exchange.Code, exchange.Body.String())
	}
}

func TestClientCredentialsProjectsMachineGrantThroughRuntimeOnly(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeCreateSession = func(context.Context, runtimegrpc.SessionCreateCredentials, sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
		t.Fatal("client_credentials was substituted with session/password creation")
		return sessionsemantic.CreateResponse{}, runtimegrpc.SessionIssuedCredentials{}, nil
	}
	config.RuntimeExchangeAuthorization = func(_ context.Context, credentials runtimegrpc.AuthorizationExchangeCredentials, request authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		if credentials.ClientSecret != "machine-secret" || credentials.AuthorizationCode != "" || credentials.CodeVerifier != "" || credentials.RefreshToken != "" {
			t.Fatalf("credentials=%#v", credentials)
		}
		if request.GrantType != authorizationsemantic.GrantTypeClientCredentials || request.ClientID != "confidential-client" ||
			request.RequestedScope != "api.read" || request.RedirectURI != "" || request.Issuer != "https://crm.example.test" {
			t.Fatalf("request=%#v", request)
		}
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, Scope: "api.read", AccessTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "machine-access-token"}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"}, "scope": {"api.read"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusOK || response.Header().Get("Cache-Control") != "no-store" || response.Header().Get("Pragma") != "no-cache" ||
		!strings.Contains(response.Body.String(), `"access_token":"machine-access-token"`) ||
		!strings.Contains(response.Body.String(), `"scope":"api.read"`) || strings.Contains(response.Body.String(), "refresh_token") ||
		strings.Contains(response.Body.String(), "machine-secret") {
		t.Fatalf("status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String())
	}
}

func TestClientCredentialsProjectsSanitizedRuntimeDenials(t *testing.T) {
	for _, test := range []struct {
		runtimeCode string
		wantStatus  int
		wantCode    string
	}{
		{runtimeCode: "invalid_client", wantStatus: http.StatusBadRequest, wantCode: "invalid_client"},
		{runtimeCode: "invalid_grant", wantStatus: http.StatusBadRequest, wantCode: "invalid_grant"},
		{runtimeCode: "invalid_scope", wantStatus: http.StatusBadRequest, wantCode: "invalid_scope"},
		{runtimeCode: "unauthorized_client", wantStatus: http.StatusForbidden, wantCode: "access_denied"},
	} {
		t.Run(test.runtimeCode, func(t *testing.T) {
			config := sessionTestConfig()
			config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
				return authorizationsemantic.ExchangeResponse{ProtocolError: &authorizationsemantic.ProtocolError{
					Code: test.runtimeCode, SafeDescription: "request rejected",
				}}, runtimegrpc.IssuedAuthorizationCredentials{}, nil
			}
			session, err := newSessionHTTP(config)
			if err != nil {
				t.Fatal(err)
			}
			form := url.Values{
				"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
				"client_secret": {"credential-must-not-leak"},
			}
			request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
			request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			response := httptest.NewRecorder()
			session.serve(response, request)
			if response.Code != test.wantStatus || !strings.Contains(response.Body.String(), `"error":"`+test.wantCode+`"`) ||
				strings.Contains(response.Body.String(), "credential-must-not-leak") {
				t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
			}
		})
	}
}

func TestClientCredentialsProtocolErrorRevokesIssuedAccessToken(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{ProtocolError: &authorizationsemantic.ProtocolError{
			Code: "invalid_client", SafeDescription: "request rejected",
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "orphan-access-token"}, nil
	}
	var revoked runtimegrpc.SessionPresentedCredentials
	config.RuntimeRevokeSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, _ sessionsemantic.RevokeRequest) error {
		revoked = credentials
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusInternalServerError || revoked.AccessToken != "orphan-access-token" ||
		strings.Contains(response.Body.String(), "orphan-access-token") || strings.Contains(response.Body.String(), "machine-secret") {
		t.Fatalf("status=%d revoked=%#v body=%s", response.Code, revoked, response.Body.String())
	}
}

func TestClientCredentialsRejectsUnexpectedRefreshCredentialAndRevokesSession(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true, RefreshTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "machine-access-token", RefreshToken: "unexpected-refresh-token"}, nil
	}
	var revoked runtimegrpc.SessionPresentedCredentials
	config.RuntimeRevokeSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, _ sessionsemantic.RevokeRequest) error {
		revoked = credentials
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusInternalServerError || revoked.AccessToken != "machine-access-token" ||
		strings.Contains(response.Body.String(), "machine-access-token") || strings.Contains(response.Body.String(), "unexpected-refresh-token") {
		t.Fatalf("status=%d revoked=%#v body=%s", response.Code, revoked, response.Body.String())
	}
}

type failingOAuthResponseWriter struct {
	header http.Header
	status int
}

func (writer *failingOAuthResponseWriter) Header() http.Header {
	if writer.header == nil {
		writer.header = make(http.Header)
	}
	return writer.header
}
func (writer *failingOAuthResponseWriter) WriteHeader(status int) { writer.status = status }
func (*failingOAuthResponseWriter) Write([]byte) (int, error) {
	return 0, errors.New("client disconnected")
}

func TestClientCredentialsRevokesSessionWhenTokenResponseCannotBePublished(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "machine-access-token"}, nil
	}
	var revoked runtimegrpc.SessionPresentedCredentials
	var revokeRequest sessionsemantic.RevokeRequest
	config.RuntimeRevokeSession = func(ctx context.Context, credentials runtimegrpc.SessionPresentedCredentials, request sessionsemantic.RevokeRequest) error {
		if ctx.Err() != nil {
			t.Fatalf("rollback inherited canceled response context: %v", ctx.Err())
		}
		revoked, revokeRequest = credentials, request
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	canceled, cancel := context.WithCancel(request.Context())
	cancel()
	request = request.WithContext(canceled)
	writer := &failingOAuthResponseWriter{}
	session.serve(writer, request)
	if writer.status != http.StatusOK || revoked.AccessToken != "machine-access-token" || revoked.ControlProof != "" || revokeRequest.UseControlProof {
		t.Fatalf("status=%d revoked=%#v request=%#v", writer.status, revoked, revokeRequest)
	}
}

func TestClientCredentialsWriteFailureRetriesAndRedactsRollbackFailure(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "orphan-access-token"}, nil
	}
	var revokeCalls atomic.Int32
	config.RuntimeRevokeSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
		revokeCalls.Add(1)
		return &sessionsemantic.Failure{Category: sessionsemantic.FailureCategory("UNAVAILABLE\norphan-access-token machine-secret")}
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	originalWriter, originalFlags, originalPrefix := log.Writer(), log.Flags(), log.Prefix()
	var logs bytes.Buffer
	log.SetOutput(&logs)
	log.SetFlags(0)
	log.SetPrefix("")
	defer func() {
		log.SetOutput(originalWriter)
		log.SetFlags(originalFlags)
		log.SetPrefix(originalPrefix)
	}()
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	writer := &failingOAuthResponseWriter{}
	session.serve(writer, request)
	if writer.status != http.StatusOK || revokeCalls.Load() != clientCredentialsRollbackAttempts ||
		!strings.Contains(logs.String(), "category=UNCLASSIFIED") ||
		strings.Contains(logs.String(), "orphan-access-token") || strings.Contains(logs.String(), "machine-secret") {
		t.Fatalf("status=%d revokeCalls=%d logs=%q", writer.status, revokeCalls.Load(), logs.String())
	}
}

func TestClientCredentialsMalformedSuccessRevokesIssuedAccessToken(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "orphan-access-token"}, nil
	}
	var revoked runtimegrpc.SessionPresentedCredentials
	config.RuntimeRevokeSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, _ sessionsemantic.RevokeRequest) error {
		revoked = credentials
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusInternalServerError || revoked.AccessToken != "orphan-access-token" ||
		strings.Contains(response.Body.String(), "orphan-access-token") {
		t.Fatalf("status=%d revoked=%#v body=%s", response.Code, revoked, response.Body.String())
	}
}

func TestClientCredentialsRollbackRetriesAndRedactsFailure(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true, RefreshTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{AccessToken: "orphan-access-token", RefreshToken: "forbidden-refresh-token"}, nil
	}
	var revokeCalls atomic.Int32
	config.RuntimeRevokeSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
		revokeCalls.Add(1)
		return errors.New("rollback failed for orphan-access-token and machine-secret")
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	originalWriter, originalFlags, originalPrefix := log.Writer(), log.Flags(), log.Prefix()
	var logs bytes.Buffer
	log.SetOutput(&logs)
	log.SetFlags(0)
	log.SetPrefix("")
	defer func() {
		log.SetOutput(originalWriter)
		log.SetFlags(originalFlags)
		log.SetPrefix(originalPrefix)
	}()
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusServiceUnavailable || revokeCalls.Load() != clientCredentialsRollbackAttempts ||
		!strings.Contains(logs.String(), "category=UNCLASSIFIED") ||
		strings.Contains(logs.String(), "orphan-access-token") || strings.Contains(logs.String(), "machine-secret") ||
		strings.Contains(response.Body.String(), "orphan-access-token") || strings.Contains(response.Body.String(), "forbidden-refresh-token") {
		t.Fatalf("status=%d revokeCalls=%d logs=%q body=%s", response.Code, revokeCalls.Load(), logs.String(), response.Body.String())
	}
}

func TestClientCredentialsRefreshOnlyInvariantNeverPublishesCredential(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeExchangeAuthorization = func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		return authorizationsemantic.ExchangeResponse{Token: &authorizationsemantic.Token{
			TokenType: "Bearer", ExpiresInSecond: 3600, AccessTokenIssued: true, RefreshTokenIssued: true,
		}}, runtimegrpc.IssuedAuthorizationCredentials{RefreshToken: "unrepresentable-refresh-token"}, nil
	}
	var revokeCalls atomic.Int32
	config.RuntimeRevokeSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
		revokeCalls.Add(1)
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	originalWriter, originalFlags, originalPrefix := log.Writer(), log.Flags(), log.Prefix()
	var logs bytes.Buffer
	log.SetOutput(&logs)
	log.SetFlags(0)
	log.SetPrefix("")
	defer func() {
		log.SetOutput(originalWriter)
		log.SetFlags(originalFlags)
		log.SetPrefix(originalPrefix)
	}()
	form := url.Values{
		"grant_type": {"client_credentials"}, "client_id": {"confidential-client"},
		"client_secret": {"machine-secret"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusInternalServerError || revokeCalls.Load() != 0 ||
		!strings.Contains(logs.String(), "category=REFRESH_WITHOUT_ACCESS") ||
		strings.Contains(logs.String(), "unrepresentable-refresh-token") || strings.Contains(logs.String(), "machine-secret") ||
		strings.Contains(response.Body.String(), "unrepresentable-refresh-token") {
		t.Fatalf("status=%d revokeCalls=%d logs=%q body=%s", response.Code, revokeCalls.Load(), logs.String(), response.Body.String())
	}
}

func TestExistingAuthorizationExchangeDoesNotAdoptMachineGrantWriteRollback(t *testing.T) {
	config := sessionTestConfig()
	var revokeCalls atomic.Int32
	config.RuntimeRevokeSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
		revokeCalls.Add(1)
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"grant_type": {"authorization_code"}, "client_id": {"public-client"},
		"code": {"authorization-code"}, "redirect_uri": {"https://client.example.test/callback"},
	}
	request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+TokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	writer := &failingOAuthResponseWriter{}
	session.serve(writer, request)
	if writer.status != http.StatusOK || revokeCalls.Load() != 0 {
		t.Fatalf("status=%d revokeCalls=%d", writer.status, revokeCalls.Load())
	}
}

func TestAuthorizationResumeRejectsAmbiguousJSONBeforeRuntime(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeCompleteAuthorization = func(context.Context, runtimegrpc.SessionPresentedCredentials, authorizationsemantic.CompleteRequest) (authorizationsemantic.CompleteResponse, runtimegrpc.IssuedAuthorizationCredentials, error) {
		t.Fatal("invalid browser payload reached Runtime")
		return authorizationsemantic.CompleteResponse{}, runtimegrpc.IssuedAuthorizationCredentials{}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	for _, body := range []string{
		`{"continue":"handle-1","unexpected":true}`,
		`{"continue":"handle-1"}{"continue":"handle-2"}`,
		`{"continue":""}`,
	} {
		request := httptest.NewRequest(http.MethodPost, "https://crm.example.test"+AuthorizeResumePath, strings.NewReader(body))
		request.Header.Set("Content-Type", "application/json")
		request.Header.Set("Authorization", "Bearer browser-token")
		response := httptest.NewRecorder()
		session.serve(response, request)
		if response.Code != http.StatusBadRequest {
			t.Fatalf("body=%s status=%d response=%s", body, response.Code, response.Body.String())
		}
	}
}

func protectedSessionHandler(t *testing.T, session *sessionHTTP) http.Handler {
	t.Helper()
	admission, err := apihostmiddleware.NewSessionControlHTTPAdmission("https://crm.example.test")
	if err != nil {
		t.Fatal(err)
	}
	return apihostmiddleware.ProtectSessionCredentialResponses(admission(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !session.serve(w, r) {
			http.NotFound(w, r)
		}
	})))
}

func controlledRequest(method, target string, body io.Reader, withProof bool) *http.Request {
	request := httptest.NewRequest(method, target, body)
	request.Header.Set(apihostmiddleware.HeaderSessionControlIntent, apihostmiddleware.SessionControlIntentValue)
	request.Header.Set("Origin", "https://crm.example.test")
	request.Header.Set("Sec-Fetch-Site", "same-origin")
	if withProof {
		request.AddCookie(&http.Cookie{Name: apihostmiddleware.SessionControlCookieName, Value: sessionTestProof})
	}
	return request
}

func TestSessionLoginOptionsAndPasswordCreateUseOneRuntimeOwner(t *testing.T) {
	config := sessionTestConfig()
	config.RequireBrowserSessionControl = true
	config.GoogleClientID = "google-client"
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) { return "id-token", nil }
	var createCalls atomic.Int64
	config.RuntimeCreateSession = func(_ context.Context, credentials runtimegrpc.SessionCreateCredentials, request sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
		createCalls.Add(1)
		if credentials.Identity != "user@example.test" || credentials.Secret != "passwordsecurity" || credentials.ClientSecret != "client-secret" {
			t.Fatalf("credentials=%#v", credentials)
		}
		if request.Method != sessionsemantic.AuthenticationMethodPassword || request.ApplicationClientID != "nexuscrm-ui" || !request.IssueControlProof {
			t.Fatalf("request=%#v", request)
		}
		return sessionsemantic.CreateResponse{
			Session: sessionTestResponse(), AccessTokenIssued: true, ControlProofIssued: true,
		}, runtimegrpc.SessionIssuedCredentials{AccessToken: "access-token", ControlProof: sessionTestProof}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	handler := protectedSessionHandler(t, session)

	options := httptest.NewRecorder()
	handler.ServeHTTP(options, controlledRequest(http.MethodGet, LoginOptionsPath, nil, false))
	var optionsBody struct {
		Providers              []publicLoginProvider `json:"providers"`
		SessionControlEnabled  bool                  `json:"sessionControlEnabled"`
		SessionControlRequired bool                  `json:"sessionControlRequired"`
	}
	if err := json.Unmarshal(options.Body.Bytes(), &optionsBody); err != nil {
		t.Fatal(err)
	}
	if options.Code != http.StatusOK || !optionsBody.SessionControlEnabled ||
		!optionsBody.SessionControlRequired || len(optionsBody.Providers) != 3 {
		t.Fatalf("options status=%d body=%s", options.Code, options.Body.String())
	}

	form := url.Values{
		"grant_type": {"password"}, "username": {"user@example.test"},
		"password": {"password"}, "security_token": {"security"},
		"client_id": {"nexuscrm-ui"}, "client_secret": {"client-secret"},
	}
	request := controlledRequest(http.MethodPost, TokenPath, strings.NewReader(form.Encode()), false)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	handler.ServeHTTP(response, request)
	if response.Code != http.StatusOK || createCalls.Load() != 1 || !strings.Contains(response.Body.String(), `"access_token":"access-token"`) {
		t.Fatalf("token status=%d calls=%d body=%s", response.Code, createCalls.Load(), response.Body.String())
	}
	if strings.Contains(response.Body.String(), sessionTestProof) || response.Header().Get(apihostmiddleware.HeaderRefreshedToken) != "" {
		t.Fatalf("credential leaked outside initial token/cookie boundary: headers=%v body=%s", response.Header(), response.Body.String())
	}
	var foundControlCookie bool
	for _, cookie := range response.Result().Cookies() {
		if cookie.Name == apihostmiddleware.SessionControlCookieName {
			foundControlCookie = cookie.Value == sessionTestProof && cookie.HttpOnly && cookie.Secure && cookie.SameSite == http.SameSiteStrictMode
		}
	}
	if !foundControlCookie {
		t.Fatalf("protected session-control cookie missing: %v", response.Result().Cookies())
	}
}

func TestGoogleLoginStateIsIssuedAndConsumedBeforeProviderExchange(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = true
	var events []string
	config.RuntimeBeginFederatedLogin = func(_ context.Context, request federatedloginsemantic.BeginRequest) (federatedloginsemantic.BeginResponse, error) {
		events = append(events, "begin")
		if request.RedirectURI != "https://crm.example.test/oauth/callback" {
			t.Fatalf("begin request=%#v", request)
		}
		return federatedloginsemantic.BeginResponse{
			State: federatedLoginTestState, ExpiresAtUnixSecond: time.Unix(1_800_000_000, 0).Unix(),
		}, nil
	}
	config.RuntimeConsumeFederatedLogin = func(_ context.Context, request federatedloginsemantic.ConsumeRequest) error {
		events = append(events, "consume")
		if request.State != federatedLoginTestState || request.RedirectURI != "https://crm.example.test/oauth/callback" {
			t.Fatalf("consume request=%#v", request)
		}
		return nil
	}
	config.FederatedCodeExchange = func(_ context.Context, code, redirectURI string) (string, error) {
		events = append(events, "provider")
		if code != "google-code" || redirectURI != "https://crm.example.test/oauth/callback" {
			t.Fatalf("provider code=%q redirect=%q", code, redirectURI)
		}
		return "id-token", nil
	}
	config.RuntimeCreateSession = func(_ context.Context, credentials runtimegrpc.SessionCreateCredentials, request sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
		events = append(events, "create")
		if credentials.Secret != "id-token" || request.Method != sessionsemantic.AuthenticationMethodFederatedIDToken {
			t.Fatalf("credentials=%#v request=%#v", credentials, request)
		}
		return sessionsemantic.CreateResponse{Session: sessionTestResponse(), AccessTokenIssued: true}, runtimegrpc.SessionIssuedCredentials{AccessToken: "access-token"}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}

	beginForm := url.Values{"redirect_uri": {"https://crm.example.test/oauth/callback"}}
	beginRequest := httptest.NewRequest(http.MethodPost, GoogleLoginStatePath, strings.NewReader(beginForm.Encode()))
	beginRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	beginResponse := httptest.NewRecorder()
	session.serve(beginResponse, beginRequest)
	if beginResponse.Code != http.StatusOK || !strings.Contains(beginResponse.Body.String(), `"state":"`+federatedLoginTestState+`"`) ||
		!strings.Contains(beginResponse.Body.String(), `"expires_at":"2027-01-15T08:00:00Z"`) {
		t.Fatalf("begin status=%d body=%s", beginResponse.Code, beginResponse.Body.String())
	}

	tokenForm := url.Values{
		"code": {"google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
		"state": {federatedLoginTestState},
	}
	tokenRequest := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(tokenForm.Encode()))
	tokenRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	tokenResponse := httptest.NewRecorder()
	session.serve(tokenResponse, tokenRequest)
	if tokenResponse.Code != http.StatusOK || strings.Join(events, ",") != "begin,consume,provider,create" {
		t.Fatalf("token status=%d events=%q body=%s", tokenResponse.Code, events, tokenResponse.Body.String())
	}
}

func TestGoogleLoginStateFailureIsNonDisclosingAndStopsBeforeProvider(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = true
	config.RuntimeBeginFederatedLogin = func(context.Context, federatedloginsemantic.BeginRequest) (federatedloginsemantic.BeginResponse, error) {
		return federatedloginsemantic.BeginResponse{}, nil
	}
	config.RuntimeConsumeFederatedLogin = func(context.Context, federatedloginsemantic.ConsumeRequest) error {
		return &federatedloginsemantic.Failure{Category: federatedloginsemantic.FailureUnauthenticated}
	}
	var providerCalls atomic.Int64
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		providerCalls.Add(1)
		return "", nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"code": {"google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
		"state": {federatedLoginTestState},
	}
	request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusBadRequest || providerCalls.Load() != 0 ||
		!strings.Contains(response.Body.String(), `"error":"invalid_grant"`) ||
		!strings.Contains(response.Body.String(), "invalid or expired") {
		t.Fatalf("status=%d provider=%d body=%s", response.Code, providerCalls.Load(), response.Body.String())
	}
}

func TestGoogleTokenAllowsPreUpgradeCallbackOnlyWhileRolloutFenceIsOpen(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = false
	var consumeCalls, providerCalls atomic.Int64
	config.RuntimeConsumeFederatedLogin = func(context.Context, federatedloginsemantic.ConsumeRequest) error {
		consumeCalls.Add(1)
		return nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		providerCalls.Add(1)
		return "id-token", nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"code": {"pre-upgrade-google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
	}
	request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusOK || consumeCalls.Load() != 0 || providerCalls.Load() != 1 {
		t.Fatalf("status=%d consume=%d provider=%d body=%s", response.Code, consumeCalls.Load(), providerCalls.Load(), response.Body.String())
	}
}

func TestGoogleTokenAllowsPreUpgradeBrowserLocalStateOnlyWhileRolloutFenceIsOpen(t *testing.T) {
	const browserLocalState = "google:00000000-0000-4000-8000-000000000000"
	for _, test := range []struct {
		name               string
		state              string
		requireState       bool
		wantConsumeCalls   int64
		wantProviderCalls  int64
		wantDescription    string
		consumeReturnsFail bool
	}{
		{
			name: "compatibility", state: browserLocalState, wantConsumeCalls: 0, wantProviderCalls: 1,
			wantDescription: "Google authorization code exchange failed",
		},
		{
			name: "malformed compatibility state", state: "google:not-a-uuid", wantConsumeCalls: 1,
			wantDescription:    "login state is invalid or expired; start the sign-in again",
			consumeReturnsFail: true,
		},
		{
			name: "strict", state: browserLocalState, requireState: true, wantConsumeCalls: 1,
			wantDescription:    "login state is invalid or expired; start the sign-in again",
			consumeReturnsFail: true,
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			config := sessionTestConfig()
			config.GoogleClientID = "google-client"
			config.RequireFederatedLoginState = test.requireState
			var consumeCalls, providerCalls atomic.Int64
			config.RuntimeConsumeFederatedLogin = func(context.Context, federatedloginsemantic.ConsumeRequest) error {
				consumeCalls.Add(1)
				if test.consumeReturnsFail {
					return &federatedloginsemantic.Failure{Category: federatedloginsemantic.FailureUnauthenticated}
				}
				return nil
			}
			config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
				providerCalls.Add(1)
				return "", errors.New("reject test code")
			}
			session, err := newSessionHTTP(config)
			if err != nil {
				t.Fatal(err)
			}
			form := url.Values{
				"code": {"pre-upgrade-google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
				"state": {test.state},
			}
			request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
			request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			response := httptest.NewRecorder()
			session.serve(response, request)
			if response.Code != http.StatusBadRequest || consumeCalls.Load() != test.wantConsumeCalls ||
				providerCalls.Load() != test.wantProviderCalls || !strings.Contains(response.Body.String(), test.wantDescription) {
				t.Fatalf("status=%d consume=%d provider=%d body=%s", response.Code, consumeCalls.Load(), providerCalls.Load(), response.Body.String())
			}
		})
	}
}

func TestGoogleTokenStillConsumesPresentStateWhileRolloutFenceIsOpen(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = false
	var consumeCalls, providerCalls atomic.Int64
	config.RuntimeConsumeFederatedLogin = func(_ context.Context, request federatedloginsemantic.ConsumeRequest) error {
		consumeCalls.Add(1)
		if request.State != federatedLoginTestState {
			t.Fatalf("consume request=%#v", request)
		}
		return nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		providerCalls.Add(1)
		return "id-token", nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"code": {"stateful-google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
		"state": {federatedLoginTestState},
	}
	request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusOK || consumeCalls.Load() != 1 || providerCalls.Load() != 1 {
		t.Fatalf("status=%d consume=%d provider=%d body=%s", response.Code, consumeCalls.Load(), providerCalls.Load(), response.Body.String())
	}
}

func TestGoogleTokenProjectsTheExactPreUpgradeStateIntoTheNeutralRuntimeContract(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = true
	entropy := make([]byte, federatedloginsemantic.StateEntropyBytes)
	legacyState := "ssologin." + base64.URLEncoding.EncodeToString(entropy)
	canonicalState := base64.RawURLEncoding.EncodeToString(entropy)
	var consumed string
	config.RuntimeConsumeFederatedLogin = func(_ context.Context, request federatedloginsemantic.ConsumeRequest) error {
		consumed = request.State
		return nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		return "", errors.New("stop after state projection")
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{
		"code": {"google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
		"state": {legacyState},
	}
	request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusBadRequest || consumed != canonicalState {
		t.Fatalf("status=%d consumed=%q want canonical=%q body=%s", response.Code, consumed, canonicalState, response.Body.String())
	}
}

func TestGoogleLoginStateRouteProbeIsNonMutatingWhenProviderIsUnconfigured(t *testing.T) {
	config := sessionTestConfig()
	var beginCalls atomic.Int64
	config.RuntimeBeginFederatedLogin = func(context.Context, federatedloginsemantic.BeginRequest) (federatedloginsemantic.BeginResponse, error) {
		beginCalls.Add(1)
		return federatedloginsemantic.BeginResponse{}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	request := httptest.NewRequest(http.MethodPost, GoogleLoginStatePath, strings.NewReader(""))
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	session.serve(response, request)
	if response.Code != http.StatusBadRequest || beginCalls.Load() != 0 ||
		!strings.Contains(response.Body.String(), `"error":"invalid_request"`) {
		t.Fatalf("status=%d begin=%d body=%s", response.Code, beginCalls.Load(), response.Body.String())
	}
}

func TestGoogleTokenRequiresOneStateAndValidatesRedirectBeforeConsumption(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	config.RequireFederatedLoginState = true
	var consumeCalls, providerCalls atomic.Int64
	config.RuntimeConsumeFederatedLogin = func(context.Context, federatedloginsemantic.ConsumeRequest) error {
		consumeCalls.Add(1)
		return nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		providerCalls.Add(1)
		return "id-token", nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}

	for name, form := range map[string]url.Values{
		"missing state": {
			"code": {"google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
		},
		"duplicate state": {
			"code": {"google-code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"},
			"state": {federatedLoginTestState, federatedLoginTestState},
		},
		"wrong redirect": {
			"code": {"google-code"}, "redirect_uri": {"https://evil.example.test/oauth/callback"},
			"state": {federatedLoginTestState},
		},
	} {
		t.Run(name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(form.Encode()))
			request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			response := httptest.NewRecorder()
			session.serve(response, request)
			if response.Code != http.StatusBadRequest {
				t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
			}
		})
	}
	if consumeCalls.Load() != 0 || providerCalls.Load() != 0 {
		t.Fatalf("consume=%d provider=%d", consumeCalls.Load(), providerCalls.Load())
	}
}

func TestRequiredBrowserSessionControlRejectsFallbackBeforeOwners(t *testing.T) {
	config := sessionTestConfig()
	config.RequireBrowserSessionControl = true
	config.GoogleClientID = "google-client"
	var createCalls, exchangeCalls atomic.Int64
	config.RuntimeCreateSession = func(_ context.Context, _ runtimegrpc.SessionCreateCredentials, request sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
		createCalls.Add(1)
		if request.ApplicationClientID != "api-client" || request.IssueControlProof {
			t.Fatalf("non-browser request=%#v", request)
		}
		return sessionsemantic.CreateResponse{
			Session: sessionTestResponse(), AccessTokenIssued: true,
		}, runtimegrpc.SessionIssuedCredentials{AccessToken: "api-token"}, nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		exchangeCalls.Add(1)
		return "id-token", nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	handler := protectedSessionHandler(t, session)

	passwordForm := url.Values{
		"grant_type": {"password"}, "username": {"user@example.test"},
		"password": {"password"}, "client_id": {browserSessionClientID},
	}
	passwordRequest := httptest.NewRequest(http.MethodPost, TokenPath, strings.NewReader(passwordForm.Encode()))
	passwordRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	passwordResponse := httptest.NewRecorder()
	handler.ServeHTTP(passwordResponse, passwordRequest)
	if passwordResponse.Code != http.StatusBadRequest || createCalls.Load() != 0 {
		t.Fatalf("uncontrolled browser password status=%d creates=%d body=%s", passwordResponse.Code, createCalls.Load(), passwordResponse.Body.String())
	}

	googleForm := url.Values{"code": {"code"}, "redirect_uri": {"https://crm.example.test/oauth/callback"}}
	googleRequest := httptest.NewRequest(http.MethodPost, GoogleTokenPath, strings.NewReader(googleForm.Encode()))
	googleRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	googleResponse := httptest.NewRecorder()
	handler.ServeHTTP(googleResponse, googleRequest)
	if googleResponse.Code != http.StatusBadRequest || exchangeCalls.Load() != 0 || createCalls.Load() != 0 {
		t.Fatalf("uncontrolled browser federated status=%d exchanges=%d creates=%d body=%s", googleResponse.Code, exchangeCalls.Load(), createCalls.Load(), googleResponse.Body.String())
	}

	apiForm := url.Values{
		"grant_type": {"password"}, "username": {"user@example.test"},
		"password": {"password"}, "client_id": {"api-client"},
	}
	for name, headers := range map[string]map[string]string{
		"origin":         {"Origin": "https://crm.example.test"},
		"fetch metadata": {"Sec-Fetch-Site": "same-origin"},
	} {
		t.Run("alternate client ID cannot bypass "+name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodPost, TokenPath, strings.NewReader(apiForm.Encode()))
			request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			for key, value := range headers {
				request.Header.Set(key, value)
			}
			response := httptest.NewRecorder()
			handler.ServeHTTP(response, request)
			if response.Code != http.StatusBadRequest || createCalls.Load() != 0 {
				t.Fatalf("uncontrolled browser alternate-client status=%d creates=%d body=%s", response.Code, createCalls.Load(), response.Body.String())
			}
		})
	}

	apiRequest := httptest.NewRequest(http.MethodPost, TokenPath, strings.NewReader(apiForm.Encode()))
	apiRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	apiResponse := httptest.NewRecorder()
	handler.ServeHTTP(apiResponse, apiRequest)
	if apiResponse.Code != http.StatusOK || createCalls.Load() != 1 ||
		!strings.Contains(apiResponse.Body.String(), `"access_token":"api-token"`) {
		t.Fatalf("non-browser password status=%d creates=%d body=%s", apiResponse.Code, createCalls.Load(), apiResponse.Body.String())
	}
}

func TestRequestPublicOriginTrustsForwardedHeadersOnlyFromPrivateProxy(t *testing.T) {
	external := httptest.NewRequest(http.MethodGet, "http://internal-sfcrm.test/services/oauth2/authorize", nil)
	external.RemoteAddr = "203.0.113.9:443"
	external.Header.Set("X-Forwarded-Proto", "https")
	external.Header.Set("X-Forwarded-Host", "attacker.example.test")
	if got := requestPublicOrigin(external); got != "http://internal-sfcrm.test" {
		t.Fatalf("external forwarded origin must be ignored: %q", got)
	}

	privateProxy := httptest.NewRequest(http.MethodGet, "http://internal-sfcrm.test/services/oauth2/authorize", nil)
	privateProxy.RemoteAddr = "10.0.0.8:8443"
	privateProxy.Header.Set("X-Forwarded-Proto", "https")
	privateProxy.Header.Set("X-Forwarded-Host", "crm.example.test")
	if got := requestPublicOrigin(privateProxy); got != "https://crm.example.test" {
		t.Fatalf("private proxy forwarded origin=%q", got)
	}
}

func TestSessionUserInfoRenewsPairAndUsesReplacementForPermissions(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeReadSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, request sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
		if credentials.AccessToken != "old-token" || credentials.ControlProof != sessionTestProof || !request.AllowRenewal || !request.UseControlProof {
			t.Fatalf("read credentials=%#v request=%#v", credentials, request)
		}
		return sessionsemantic.ReadResponse{
			Session: sessionTestResponse(), ReplacementAccessTokenIssued: true,
			ControlProofExpiresAtUnixSecond: time.Now().Add(time.Hour).Unix(),
		}, runtimegrpc.SessionIssuedCredentials{AccessToken: "new-token"}, nil
	}
	config.RuntimeReadEffective = func(_ context.Context, bearer string, request effectivepermissionssemantic.Request) (effectivepermissionssemantic.Response, error) {
		if bearer != "new-token" || request.TargetPrincipalID != "" ||
			request.Selection == nil || len(request.Selection.Sections) != 1 ||
			request.Selection.Sections[0] != effectivepermissionssemantic.SectionSystemPermissions ||
			len(request.Selection.ResourceTypes) != 0 {
			t.Fatalf("effective bearer=%q request=%#v", bearer, request)
		}
		return effectivepermissionssemantic.Response{SystemPermissions: []effectivepermissionssemantic.PermissionGrant{{PermissionID: "ViewSetup", Granted: true}}}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	request := controlledRequest(http.MethodGet, UserInfoPath, nil, true)
	request.Header.Set("Authorization", "Bearer old-token")
	response := httptest.NewRecorder()
	protectedSessionHandler(t, session).ServeHTTP(response, request)
	if response.Code != http.StatusOK || response.Header().Get(apihostmiddleware.HeaderRefreshedToken) != "new-token" {
		t.Fatalf("userinfo status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String())
	}
	if !strings.Contains(response.Body.String(), `"organization_id":"org-1"`) ||
		!strings.Contains(response.Body.String(), `"ViewSetup":true`) {
		t.Fatalf("userinfo body=%s", response.Body.String())
	}
}

func TestSessionUserInfoPublishesDurableRenewalWhenDownstreamReadFails(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeReadSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, request sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
		if credentials.AccessToken != "old-token" || credentials.ControlProof != sessionTestProof ||
			!request.AllowRenewal || !request.UseControlProof {
			t.Fatalf("read credentials=%#v request=%#v", credentials, request)
		}
		return sessionsemantic.ReadResponse{
			Session: sessionTestResponse(), ReplacementAccessTokenIssued: true,
			ControlProofExpiresAtUnixSecond: time.Now().Add(time.Hour).Unix(),
		}, runtimegrpc.SessionIssuedCredentials{AccessToken: "new-token"}, nil
	}
	config.RuntimeReadEffective = func(context.Context, string, effectivepermissionssemantic.Request) (effectivepermissionssemantic.Response, error) {
		return effectivepermissionssemantic.Response{}, errors.New("downstream permission read failed")
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	request := controlledRequest(http.MethodGet, UserInfoPath, nil, true)
	request.Header.Set("Authorization", "Bearer old-token")
	response := httptest.NewRecorder()
	protectedSessionHandler(t, session).ServeHTTP(response, request)

	if response.Code == http.StatusOK || response.Header().Get(apihostmiddleware.HeaderRefreshedToken) != "new-token" ||
		response.Header().Get("Cache-Control") != "no-store" {
		t.Fatalf("status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String())
	}
	var renewedProof bool
	for _, cookie := range response.Result().Cookies() {
		if cookie.Name == apihostmiddleware.SessionControlCookieName && cookie.Value == sessionTestProof {
			renewedProof = true
		}
	}
	if !renewedProof {
		t.Fatalf("durable renewal response lost proof cookie: %v", response.Result().Cookies())
	}
}

func TestControlledBusinessRequestRenewsBeforeRuntimeDispatch(t *testing.T) {
	config := sessionTestConfig()
	config.RuntimeReadSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, request sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
		if credentials.AccessToken != "old-token" || credentials.ControlProof != sessionTestProof || !request.AllowRenewal || !request.UseControlProof {
			t.Fatalf("read credentials=%#v request=%#v", credentials, request)
		}
		return sessionsemantic.ReadResponse{
			Session: sessionTestResponse(), ReplacementAccessTokenIssued: true,
			ControlProofExpiresAtUnixSecond: time.Now().Add(time.Hour).Unix(),
		}, runtimegrpc.SessionIssuedCredentials{AccessToken: "new-token"}, nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	admission, err := apihostmiddleware.NewSessionControlHTTPAdmission("https://crm.example.test")
	if err != nil {
		t.Fatal(err)
	}
	var downstreamBearer string
	handler := apihostmiddleware.ProtectSessionCredentialResponses(admission(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !session.prepareControlledRequest(w, r) {
			return
		}
		downstreamBearer = r.Header.Get("Authorization")
		w.WriteHeader(http.StatusNoContent)
	})))
	request := controlledRequest(http.MethodGet, "/services/data/v63.0/query", nil, true)
	request.Header.Set("Authorization", "Bearer old-token")
	response := httptest.NewRecorder()
	handler.ServeHTTP(response, request)
	if response.Code != http.StatusNoContent || downstreamBearer != "Bearer new-token" ||
		response.Header().Get(apihostmiddleware.HeaderRefreshedToken) != "new-token" {
		t.Fatalf("status=%d downstream=%q headers=%v", response.Code, downstreamBearer, response.Header())
	}
}

func TestSessionControlAndStaleAuthorityFailClosed(t *testing.T) {
	config := sessionTestConfig()
	var readCalls atomic.Int64
	config.RuntimeReadSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
		readCalls.Add(1)
		return sessionsemantic.ReadResponse{}, runtimegrpc.SessionIssuedCredentials{}, &sessionsemantic.Failure{
			Category: sessionsemantic.FailureStaleState, StaleAxis: sessionsemantic.StaleAxisSecurity,
		}
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	handler := protectedSessionHandler(t, session)

	badOrigin := controlledRequest(http.MethodGet, UserInfoPath, nil, true)
	badOrigin.Header.Set("Origin", "https://attacker.example")
	badOrigin.Header.Set("Authorization", "Bearer old-token")
	badResponse := httptest.NewRecorder()
	handler.ServeHTTP(badResponse, badOrigin)
	if badResponse.Code != http.StatusUnauthorized || readCalls.Load() != 0 {
		t.Fatalf("bad control status=%d calls=%d body=%s", badResponse.Code, readCalls.Load(), badResponse.Body.String())
	}

	stale := controlledRequest(http.MethodGet, UserInfoPath, nil, true)
	stale.Header.Set("Authorization", "Bearer old-token")
	staleResponse := httptest.NewRecorder()
	handler.ServeHTTP(staleResponse, stale)
	if staleResponse.Code != http.StatusServiceUnavailable || readCalls.Load() != 1 ||
		staleResponse.Header().Get(apihostmiddleware.HeaderRefreshedToken) != "" {
		t.Fatalf("stale status=%d calls=%d headers=%v body=%s", staleResponse.Code, readCalls.Load(), staleResponse.Header(), staleResponse.Body.String())
	}
}

func TestSessionRuntimeFailureLogsAdmissionEvidenceWithoutSensitiveErrors(t *testing.T) {
	originalWriter, originalFlags, originalPrefix := log.Writer(), log.Flags(), log.Prefix()
	var logs bytes.Buffer
	log.SetOutput(&logs)
	log.SetFlags(0)
	log.SetPrefix("")
	defer func() {
		log.SetOutput(originalWriter)
		log.SetFlags(originalFlags)
		log.SetPrefix(originalPrefix)
	}()

	response := httptest.NewRecorder()
	writeSessionCRMFailure(response, &sessionsemantic.Failure{
		Category:         sessionsemantic.FailureResourceExhausted,
		LimitKind:        sessionsemantic.LimitAdmission,
		Maximum:          16,
		RetryAfterMillis: 50,
		RequestID:        "runtime-request-1",
	})
	if response.Code != http.StatusServiceUnavailable {
		t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
	}
	for _, expected := range []string{
		"operation=read", "category=RESOURCE_EXHAUSTED", "limit_kind=ADMISSION",
		"maximum=16", "retry_after_ms=50", "request_id=runtime-request-1",
	} {
		if !strings.Contains(logs.String(), expected) {
			t.Fatalf("missing %q in logs %q", expected, logs.String())
		}
	}

	logs.Reset()
	writeSessionCRMFailure(httptest.NewRecorder(), &sessionsemantic.Failure{
		Category: sessionsemantic.FailureCategory("UNAVAILABLE\norphan-access-token machine-secret"),
	})
	if !strings.Contains(logs.String(), "operation=read category=UNCLASSIFIED") ||
		strings.Contains(logs.String(), "orphan-access-token") ||
		strings.Contains(logs.String(), "machine-secret") {
		t.Fatalf("unsafe unclassified logs=%q", logs.String())
	}
}

func TestSessionRevokeIsProofBoundAndNonDisclosing(t *testing.T) {
	config := sessionTestConfig()
	var revoked runtimegrpc.SessionPresentedCredentials
	config.RuntimeRevokeSession = func(_ context.Context, credentials runtimegrpc.SessionPresentedCredentials, request sessionsemantic.RevokeRequest) error {
		revoked = credentials
		if !request.UseControlProof {
			t.Fatal("controlled revoke did not require proof")
		}
		return nil
	}
	session, err := newSessionHTTP(config)
	if err != nil {
		t.Fatal(err)
	}
	form := url.Values{"token": {"access-token"}}
	request := controlledRequest(http.MethodPost, RevokePath, strings.NewReader(form.Encode()), true)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response := httptest.NewRecorder()
	protectedSessionHandler(t, session).ServeHTTP(response, request)
	if response.Code != http.StatusOK || revoked.AccessToken != "access-token" || revoked.ControlProof != sessionTestProof {
		t.Fatalf("revoke status=%d credentials=%#v body=%s", response.Code, revoked, response.Body.String())
	}
	var cleared bool
	for _, cookie := range response.Result().Cookies() {
		cleared = cleared || (cookie.Name == apihostmiddleware.SessionControlCookieName && cookie.MaxAge < 0)
	}
	if !cleared {
		t.Fatalf("revoke did not clear control cookie: %v", response.Result().Cookies())
	}
}

func TestServiceDrainRejectsEverySessionRouteBeforeRuntimeOrProviderCall(t *testing.T) {
	config := sessionTestConfig()
	config.GoogleClientID = "google-client"
	var createCalls, readCalls, revokeCalls, exchangeCalls atomic.Int64
	config.RuntimeCreateSession = func(context.Context, runtimegrpc.SessionCreateCredentials, sessionsemantic.CreateRequest) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error) {
		createCalls.Add(1)
		return sessionsemantic.CreateResponse{}, runtimegrpc.SessionIssuedCredentials{}, nil
	}
	config.RuntimeReadSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.ReadRequest) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error) {
		readCalls.Add(1)
		return sessionsemantic.ReadResponse{}, runtimegrpc.SessionIssuedCredentials{}, nil
	}
	config.RuntimeRevokeSession = func(context.Context, runtimegrpc.SessionPresentedCredentials, sessionsemantic.RevokeRequest) error {
		revokeCalls.Add(1)
		return nil
	}
	config.FederatedCodeExchange = func(context.Context, string, string) (string, error) {
		exchangeCalls.Add(1)
		return "", nil
	}
	runtime := &fakeRuntime{}
	runtime.ready.Store(true)
	service, err := NewService(ServiceConfig{
		Session:         &config,
		RuntimeEvaluate: runtime.Evaluate, RuntimeReady: runtime.Ready,
		RuntimeMetrics: runtime.Metrics,
		RuntimeQuery: func(context.Context, string, querysemantic.Request) (querysemantic.Response, error) {
			return querysemantic.Response{}, nil
		},
		RuntimeHistoryQuery: func(context.Context, string, querysemantic.HistoryRequest) (querysemantic.HistoryResponse, error) {
			return querysemantic.HistoryResponse{}, nil
		},
		RequestTimeout: time.Second, MaxRequestBytes: 64 * 1024,
	})
	if err != nil {
		t.Fatal(err)
	}
	service.BeginDrain()
	for _, route := range []string{
		LoginOptionsPath, TokenPath, GoogleTokenPath, UserInfoPath, RevokePath,
	} {
		t.Run(route, func(t *testing.T) {
			response := httptest.NewRecorder()
			service.ServeHTTP(response, httptest.NewRequest(http.MethodPost, route, nil))
			if response.Code != http.StatusServiceUnavailable ||
				!strings.Contains(response.Body.String(), `"error":"temporarily_unavailable"`) {
				t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
			}
		})
	}
	if createCalls.Load() != 0 || readCalls.Load() != 0 || revokeCalls.Load() != 0 ||
		exchangeCalls.Load() != 0 {
		t.Fatalf(
			"draining calls: create=%d read=%d revoke=%d exchange=%d",
			createCalls.Load(), readCalls.Load(), revokeCalls.Load(), exchangeCalls.Load(),
		)
	}
}

type oauthRoundTripper func(*http.Request) (*http.Response, error)

func (roundTrip oauthRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
	return roundTrip(request)
}

func TestGoogleCodeExchangeIsFixedBoundedAndCancellationAware(t *testing.T) {
	client := &http.Client{Timeout: time.Second, Transport: oauthRoundTripper(func(request *http.Request) (*http.Response, error) {
		if err := request.Context().Err(); err != nil {
			return nil, err
		}
		if request.URL.String() != "https://oauth2.googleapis.com/token" || request.Method != http.MethodPost {
			t.Fatalf("request=%s %s", request.Method, request.URL)
		}
		body, err := io.ReadAll(request.Body)
		if err != nil {
			t.Fatal(err)
		}
		values, err := url.ParseQuery(string(body))
		if err != nil || values.Get("client_secret") != "google-secret" || values.Get("code") != "code" {
			t.Fatalf("form=%q err=%v", body, err)
		}
		return &http.Response{
			StatusCode: http.StatusOK, Header: make(http.Header),
			Body: io.NopCloser(strings.NewReader(`{"id_token":"signed-id-token"}`)),
		}, nil
	})}
	exchange, err := NewGoogleCodeExchange(client, "google-client", "google-secret")
	if err != nil {
		t.Fatal(err)
	}
	token, err := exchange(context.Background(), "code", "https://crm.example.test/oauth/callback")
	if err != nil || token != "signed-id-token" {
		t.Fatalf("exchange token=%q err=%v", token, err)
	}

	canceled, cancel := context.WithCancel(context.Background())
	cancel()
	if _, err := exchange(canceled, "code", "https://crm.example.test/oauth/callback"); err == nil {
		t.Fatal("canceled Google exchange succeeded")
	}
}

func TestGoogleCodeExchangeNeverForwardsClientSecretAcrossRedirect(t *testing.T) {
	var calls atomic.Int32
	client := &http.Client{Timeout: time.Second, Transport: oauthRoundTripper(func(request *http.Request) (*http.Response, error) {
		if calls.Add(1) != 1 {
			t.Fatalf("Google token request followed redirect to %s", request.URL)
		}
		return &http.Response{
			StatusCode: http.StatusTemporaryRedirect,
			Header:     http.Header{"Location": []string{"https://attacker.example/token"}},
			Body:       io.NopCloser(strings.NewReader("redirect")),
			Request:    request,
		}, nil
	})}
	exchange, err := NewGoogleCodeExchange(client, "google-client", "google-secret")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := exchange(context.Background(), "code", "https://crm.example.test/oauth/callback"); err == nil {
		t.Fatal("redirecting Google token endpoint was accepted")
	}
	if calls.Load() != 1 {
		t.Fatalf("Google transport calls = %d", calls.Load())
	}
}
