package sfcrmappservice

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"mime"
	"net"
	"net/http"
	"net/url"
	"strings"
	"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"
	federatedloginsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/federatedloginv1"
	sessionsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/sessionv1"
)

const (
	SessionCapabilityID          = "io.nexuscrm.sfcrm.session.v1"
	GoogleLoginStateCapabilityID = "io.nexuscrm.sfcrm.google-login-state.v1"
	browserSessionClientID       = "nexuscrm-ui"

	LoginOptionsPath     = "/services/oauth2/login-options"
	AuthorizePath        = "/services/oauth2/authorize"
	AuthorizeResumePath  = "/services/oauth2/authorize/resume"
	TokenPath            = "/services/oauth2/token"
	GoogleLoginStatePath = "/services/oauth2/google/login-state"
	GoogleTokenPath      = "/services/oauth2/google/token"
	UserInfoPath         = "/services/oauth2/userinfo"
	RevokePath           = "/services/oauth2/revoke"

	maxOAuthRequestBytes = 64 * 1024

	clientCredentialsRollbackAttempts = 3
	clientCredentialsRollbackTimeout  = 3 * time.Second
	clientCredentialsRollbackBackoff  = 10 * time.Millisecond
)

type RuntimeCreateSessionFunc func(
	context.Context,
	runtimegrpc.SessionCreateCredentials,
	sessionsemantic.CreateRequest,
) (sessionsemantic.CreateResponse, runtimegrpc.SessionIssuedCredentials, error)

type RuntimeReadSessionFunc func(
	context.Context,
	runtimegrpc.SessionPresentedCredentials,
	sessionsemantic.ReadRequest,
) (sessionsemantic.ReadResponse, runtimegrpc.SessionIssuedCredentials, error)

type RuntimeRevokeSessionFunc func(
	context.Context,
	runtimegrpc.SessionPresentedCredentials,
	sessionsemantic.RevokeRequest,
) error

type RuntimeBeginAuthorizationFunc func(context.Context, authorizationsemantic.BeginRequest) (authorizationsemantic.BeginResponse, error)
type RuntimeCompleteAuthorizationFunc func(context.Context, runtimegrpc.SessionPresentedCredentials, authorizationsemantic.CompleteRequest) (authorizationsemantic.CompleteResponse, runtimegrpc.IssuedAuthorizationCredentials, error)
type RuntimeExchangeAuthorizationFunc func(context.Context, runtimegrpc.AuthorizationExchangeCredentials, authorizationsemantic.ExchangeRequest) (authorizationsemantic.ExchangeResponse, runtimegrpc.IssuedAuthorizationCredentials, error)
type RuntimeBeginFederatedLoginFunc func(context.Context, federatedloginsemantic.BeginRequest) (federatedloginsemantic.BeginResponse, error)
type RuntimeConsumeFederatedLoginFunc func(context.Context, federatedloginsemantic.ConsumeRequest) error

// FederatedCodeExchangeFunc owns only the L1/provider authorization-code
// exchange. Runtime verifies the returned ID token and remains the identity and
// durable-session authority.
type FederatedCodeExchangeFunc func(context.Context, string, string) (string, error)

type SessionHTTPConfig struct {
	RuntimeCreateSession         RuntimeCreateSessionFunc
	RuntimeReadSession           RuntimeReadSessionFunc
	RuntimeRevokeSession         RuntimeRevokeSessionFunc
	RuntimeBeginAuthorization    RuntimeBeginAuthorizationFunc
	RuntimeCompleteAuthorization RuntimeCompleteAuthorizationFunc
	RuntimeExchangeAuthorization RuntimeExchangeAuthorizationFunc
	RuntimeBeginFederatedLogin   RuntimeBeginFederatedLoginFunc
	RuntimeConsumeFederatedLogin RuntimeConsumeFederatedLoginFunc
	RuntimeReadEffective         RuntimeReadEffectivePermissionsFunc
	FederatedCodeExchange        FederatedCodeExchangeFunc

	PublicOrigin            string
	OrganizationID          string
	GoogleClientID          string
	LoginMethods            []string
	PasswordGrantEnabled    bool
	PasswordBreakGlassUsers []string
	// RequireBrowserSessionControl forbids the sfcrm browser clients from
	// creating an uncontrolled session. Non-browser OAuth clients retain their
	// normal token contract.
	RequireBrowserSessionControl bool
	// RequireFederatedLoginState completes the rollout fence for browsers that
	// use the server-issued login-state initialization protocol. A present state
	// is always consumed even when this compatibility switch is false. False is
	// transitional only: restore true after pre-upgrade browser callbacks expire.
	RequireFederatedLoginState bool
}

type sessionHTTP struct {
	create                RuntimeCreateSessionFunc
	read                  RuntimeReadSessionFunc
	revoke                RuntimeRevokeSessionFunc
	beginAuthorization    RuntimeBeginAuthorizationFunc
	completeAuthorization RuntimeCompleteAuthorizationFunc
	exchangeAuthorization RuntimeExchangeAuthorizationFunc
	beginFederatedLogin   RuntimeBeginFederatedLoginFunc
	consumeFederatedLogin RuntimeConsumeFederatedLoginFunc
	readEffective         RuntimeReadEffectivePermissionsFunc
	exchange              FederatedCodeExchangeFunc

	publicOrigin          string
	organizationID        string
	googleClientID        string
	providers             []publicLoginProvider
	passwordEnabled       bool
	breakGlass            map[string]struct{}
	requireBrowserControl bool
	requireFederatedState bool
}

type publicLoginProvider struct {
	ID        string `json:"id"`
	Kind      string `json:"kind"`
	Label     string `json:"label"`
	Placement string `json:"placement"`
	ClientID  string `json:"clientId,omitempty"`
}

func newSessionHTTP(config SessionHTTPConfig) (*sessionHTTP, error) {
	if config.RuntimeCreateSession == nil || config.RuntimeReadSession == nil ||
		config.RuntimeRevokeSession == nil || config.RuntimeReadEffective == nil ||
		config.RuntimeBeginAuthorization == nil || config.RuntimeCompleteAuthorization == nil || config.RuntimeExchangeAuthorization == nil {
		return nil, errors.New("sfcrm AppService: complete Runtime session and permission ports are required")
	}
	publicOrigin, err := canonicalPublicOrigin(config.PublicOrigin)
	if err != nil {
		return nil, err
	}
	if strings.TrimSpace(config.OrganizationID) == "" || strings.TrimSpace(config.OrganizationID) != config.OrganizationID {
		return nil, errors.New("sfcrm AppService: session organization ID is required")
	}
	if !validPublicIdentifier(config.OrganizationID) {
		return nil, errors.New("sfcrm AppService: session organization ID is invalid")
	}
	googleClientID := strings.TrimSpace(config.GoogleClientID)
	googleInstalled := googleClientID != "" || config.FederatedCodeExchange != nil
	if googleInstalled && (googleClientID == "" || config.FederatedCodeExchange == nil ||
		config.RuntimeBeginFederatedLogin == nil || config.RuntimeConsumeFederatedLogin == nil) {
		return nil, errors.New("sfcrm AppService: Google client, code exchange, and Runtime federated login transaction must be installed together")
	}

	available := map[string]publicLoginProvider{
		"token": {ID: "token", Kind: "access_token", Label: "Access Token", Placement: "advanced"},
	}
	if config.PasswordGrantEnabled || len(config.PasswordBreakGlassUsers) > 0 {
		available["backend"] = publicLoginProvider{ID: "backend", Kind: "password", Label: "Backend", Placement: "advanced"}
	}
	if config.FederatedCodeExchange != nil {
		available["google"] = publicLoginProvider{
			ID: "google", Kind: "oauth2_authorization_code", Label: "Google", Placement: "primary",
			ClientID: strings.TrimSpace(config.GoogleClientID),
		}
	}
	order := normalizedLoginMethods(config.LoginMethods)
	if len(order) == 0 {
		order = []string{"google", "backend", "token"}
	}
	providers := make([]publicLoginProvider, 0, len(order))
	seen := make(map[string]struct{}, len(order))
	for _, providerID := range order {
		provider, ok := available[providerID]
		if !ok {
			continue
		}
		if _, duplicate := seen[providerID]; duplicate {
			continue
		}
		seen[providerID] = struct{}{}
		providers = append(providers, provider)
	}
	if len(providers) == 0 {
		return nil, errors.New("sfcrm AppService: session configuration exposes no login provider")
	}
	breakGlass := make(map[string]struct{}, len(config.PasswordBreakGlassUsers))
	for _, value := range config.PasswordBreakGlassUsers {
		if normalized := strings.ToLower(strings.TrimSpace(value)); normalized != "" {
			breakGlass[normalized] = struct{}{}
		}
	}
	return &sessionHTTP{
		create: config.RuntimeCreateSession, read: config.RuntimeReadSession,
		revoke: config.RuntimeRevokeSession, readEffective: config.RuntimeReadEffective,
		beginAuthorization: config.RuntimeBeginAuthorization, completeAuthorization: config.RuntimeCompleteAuthorization,
		exchangeAuthorization: config.RuntimeExchangeAuthorization,
		beginFederatedLogin:   config.RuntimeBeginFederatedLogin, consumeFederatedLogin: config.RuntimeConsumeFederatedLogin,
		exchange: config.FederatedCodeExchange, publicOrigin: publicOrigin,
		organizationID: config.OrganizationID, googleClientID: googleClientID,
		providers: providers, passwordEnabled: config.PasswordGrantEnabled, breakGlass: breakGlass,
		requireBrowserControl: config.RequireBrowserSessionControl,
		requireFederatedState: config.RequireFederatedLoginState,
	}, nil
}

func normalizedLoginMethods(values []string) []string {
	result := make([]string, 0, len(values))
	for _, raw := range values {
		for _, part := range strings.Split(raw, ",") {
			switch value := strings.ToLower(strings.TrimSpace(part)); value {
			case "google", "backend", "token":
				result = append(result, value)
			}
		}
	}
	return result
}

func canonicalPublicOrigin(raw string) (string, error) {
	if raw == "" || strings.TrimSpace(raw) != raw {
		return "", errors.New("sfcrm AppService: public origin is required")
	}
	parsed, err := url.Parse(raw)
	if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil ||
		parsed.RawQuery != "" || parsed.Fragment != "" || (parsed.Path != "" && parsed.Path != "/") {
		return "", errors.New("sfcrm AppService: public origin must be an absolute origin")
	}
	if parsed.Scheme != "https" && !(parsed.Scheme == "http" && isLoopbackHost(parsed.Hostname())) {
		return "", errors.New("sfcrm AppService: public origin must use HTTPS or loopback HTTP")
	}
	return strings.ToLower(parsed.Scheme) + "://" + strings.ToLower(parsed.Host), nil
}

func isLoopbackHost(host string) bool {
	switch strings.ToLower(host) {
	case "localhost", "127.0.0.1", "::1":
		return true
	default:
		return false
	}
}

func validPublicIdentifier(value string) bool {
	if value == "" || len(value) > sessionsemantic.MaxIdentifierBytes {
		return false
	}
	for _, character := range value {
		if (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') ||
			(character >= '0' && character <= '9') || character == '-' || character == '_' {
			continue
		}
		return false
	}
	return true
}

func (s *sessionHTTP) serve(writer http.ResponseWriter, request *http.Request) bool {
	switch request.URL.Path {
	case LoginOptionsPath:
		s.serveLoginOptions(writer, request)
	case AuthorizePath:
		s.serveAuthorize(writer, request)
	case AuthorizeResumePath:
		s.serveAuthorizeResume(writer, request)
	case TokenPath:
		s.servePasswordToken(writer, request)
	case GoogleLoginStatePath:
		s.serveGoogleLoginState(writer, request)
	case GoogleTokenPath:
		s.serveGoogleToken(writer, request)
	case UserInfoPath:
		s.serveUserInfo(writer, request)
	case RevokePath:
		s.serveRevoke(writer, request)
	default:
		return false
	}
	return true
}

func isSessionRoute(path string) bool {
	switch path {
	case LoginOptionsPath, AuthorizePath, AuthorizeResumePath, TokenPath, GoogleLoginStatePath, GoogleTokenPath, UserInfoPath, RevokePath:
		return true
	default:
		return false
	}
}

func (s *sessionHTTP) serveLoginOptions(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodGet {
		writeOAuthMethodNotAllowed(writer, http.MethodGet)
		return
	}
	writer.Header().Set("Cache-Control", "no-store")
	writeOAuthJSON(writer, http.StatusOK, map[string]any{
		"providers":              s.providers,
		"sessionControlEnabled":  apihostmiddleware.SessionControlRequestAdmitted(request.Context()),
		"sessionControlRequired": s.requireBrowserControl,
	})
}

func (s *sessionHTTP) serveAuthorize(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodGet {
		writeOAuthMethodNotAllowed(writer, http.MethodGet)
		return
	}
	query := request.URL.Query()
	for _, name := range []string{"client_id", "redirect_uri", "response_type", "scope", "state", "code_challenge", "code_challenge_method", "resource"} {
		if len(query[name]) > 1 {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "duplicate query parameter")
			return
		}
	}
	resource, resourcePresent := query.Get("resource"), len(query["resource"]) == 1
	response, err := s.beginAuthorization(request.Context(), authorizationsemantic.BeginRequest{
		ClientID: query.Get("client_id"), RedirectURI: query.Get("redirect_uri"), ResponseType: query.Get("response_type"),
		Scope: query.Get("scope"), State: query.Get("state"), CodeChallenge: query.Get("code_challenge"),
		CodeChallengeMethod: query.Get("code_challenge_method"), Issuer: requestPublicOrigin(request),
		Resource: resource, ResourcePresent: resourcePresent,
	})
	if err != nil {
		writeAuthorizationRuntimeFailure(writer, err)
		return
	}
	if response.ProtocolError != nil {
		s.writeAuthorizationProtocolError(writer, response.ProtocolError)
		return
	}
	writer.Header().Set("Cache-Control", "no-store")
	http.Redirect(writer, request, "/login?continue="+url.QueryEscape(response.RequestHandle), http.StatusFound)
}

func (s *sessionHTTP) serveAuthorizeResume(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodPost {
		writeOAuthMethodNotAllowed(writer, http.MethodPost)
		return
	}
	handle, ok := parseAuthorizationResumeRequest(writer, request)
	if !ok {
		return
	}
	bearer, ok := endUserBearer(request.Header.Values("Authorization"))
	if !ok {
		writeOAuthError(writer, http.StatusForbidden, "access_denied", "interactive login is required")
		return
	}
	response, issued, err := s.completeAuthorization(request.Context(), runtimegrpc.SessionPresentedCredentials{AccessToken: bearer}, authorizationsemantic.CompleteRequest{RequestHandle: handle})
	if err != nil {
		writeAuthorizationRuntimeFailure(writer, err)
		return
	}
	writer.Header().Set("Cache-Control", "no-store")
	writer.Header().Set("Pragma", "no-cache")
	if response.ProtocolError != nil {
		if response.ProtocolError.TrustedRedirectURI != "" {
			writeOAuthJSON(writer, http.StatusOK, map[string]any{"redirect_url": buildAuthorizationRedirect(response.ProtocolError.TrustedRedirectURI, "", response.ProtocolError.Code, response.ProtocolError.SafeDescription, response.ProtocolError.State)})
			return
		}
		s.writeAuthorizationProtocolError(writer, response.ProtocolError)
		return
	}
	if !response.AuthorizationCodeIssued || issued.AuthorizationCode == "" {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization server error")
		return
	}
	writeOAuthJSON(writer, http.StatusOK, map[string]any{"redirect_url": buildAuthorizationRedirect(response.RedirectURI, issued.AuthorizationCode, "", "", response.State)})
}

// parseAuthorizationResumeRequest owns the private browser-to-sfcrm wire
// shape. The checked-in frontend sends JSON; form input remains accepted for
// existing callers of this L1 endpoint. Both paths are bounded and reject
// ambiguous or trailing input before Runtime receives the opaque handle.
func parseAuthorizationResumeRequest(writer http.ResponseWriter, request *http.Request) (string, bool) {
	mediaType, _, err := mime.ParseMediaType(request.Header.Get("Content-Type"))
	if err != nil {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid content type")
		return "", false
	}
	if mediaType == "application/json" {
		request.Body = http.MaxBytesReader(writer, request.Body, maxOAuthRequestBytes)
		var body struct {
			Continue string `json:"continue"`
		}
		decoder := json.NewDecoder(request.Body)
		decoder.DisallowUnknownFields()
		if err := decoder.Decode(&body); err != nil || decoder.Decode(&struct{}{}) != io.EOF {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid JSON body")
			return "", false
		}
		if body.Continue == "" {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "continue handle is required")
			return "", false
		}
		return body.Continue, true
	}
	if mediaType != "application/x-www-form-urlencoded" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "unsupported content type")
		return "", false
	}
	form, ok := parseOAuthForm(writer, request)
	if !ok {
		return "", false
	}
	handle := form.Get("continue")
	if handle == "" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "continue handle is required")
		return "", false
	}
	return handle, true
}

func (s *sessionHTTP) serveAuthorizationExchange(writer http.ResponseWriter, request *http.Request, form url.Values) {
	grantType := form.Get("grant_type")
	credentials := runtimegrpc.AuthorizationExchangeCredentials{ClientSecret: form.Get("client_secret")}
	semanticRequest := authorizationsemantic.ExchangeRequest{ClientID: form.Get("client_id"), Issuer: requestPublicOrigin(request)}
	switch grantType {
	case "authorization_code":
		credentials.AuthorizationCode, credentials.CodeVerifier = form.Get("code"), form.Get("code_verifier")
		semanticRequest.GrantType, semanticRequest.RedirectURI = authorizationsemantic.GrantTypeAuthorizationCode, form.Get("redirect_uri")
		semanticRequest.Resource = form.Get("resource")
		semanticRequest.ResourcePresent = len(form["resource"]) == 1
	case "refresh_token":
		credentials.RefreshToken = form.Get("refresh_token")
		semanticRequest.GrantType, semanticRequest.RequestedScope = authorizationsemantic.GrantTypeRefreshToken, form.Get("scope")
	case "client_credentials":
		if semanticRequest.ClientID == "" || credentials.ClientSecret == "" {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "client_id and client_secret are required")
			return
		}
		semanticRequest.GrantType, semanticRequest.RequestedScope = authorizationsemantic.GrantTypeClientCredentials, form.Get("scope")
		semanticRequest.Resource = form.Get("resource")
		semanticRequest.ResourcePresent = len(form["resource"]) == 1
	default:
		writeOAuthError(writer, http.StatusBadRequest, "unsupported_grant_type", "unsupported grant type")
		return
	}
	response, issued, err := s.exchangeAuthorization(request.Context(), credentials, semanticRequest)
	if err != nil {
		writeAuthorizationRuntimeFailure(writer, err)
		return
	}
	if response.ProtocolError != nil {
		if grantType == "client_credentials" && (issued.AccessToken != "" || issued.RefreshToken != "") {
			if issued.AccessToken != "" {
				if err := s.rollbackAuthorizationAccessToken(request, issued.AccessToken); err != nil {
					logClientCredentialsRollbackFailure(err)
					writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "authorization service temporarily unavailable")
					return
				}
			} else {
				// See the equivalent success-response invariant below. The
				// released Runtime adapter rejects credentials on protocol errors,
				// including this unrepresentable refresh-only test-double shape.
				log.Printf("sfcrm client-credentials Runtime response rejected: category=PROTOCOL_REFRESH_WITHOUT_ACCESS")
			}
			writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization server error")
			return
		}
		if grantType == "client_credentials" && response.ProtocolError.Code == "unauthorized_client" {
			// Preserve the legacy Salesforce-compatible client-credentials wire
			// mapping. A disallowed grant remains invalid_grant/400; this code is
			// the Connected App access-policy denial mapped by the legacy handler.
			writeOAuthError(writer, http.StatusForbidden, "access_denied", "User is not authorized to use this Connected App")
			return
		}
		s.writeAuthorizationProtocolError(writer, response.ProtocolError)
		return
	}
	if grantType == "client_credentials" &&
		(authorizationsemantic.ValidateExchangeResponseForRequest(semanticRequest, response) != nil ||
			response.Token == nil || issued.AccessToken == "" || issued.RefreshToken != "") {
		if issued.AccessToken != "" {
			if err := s.rollbackAuthorizationAccessToken(request, issued.AccessToken); err != nil {
				logClientCredentialsRollbackFailure(err)
				writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "authorization service temporarily unavailable")
				return
			}
		} else if issued.RefreshToken != "" {
			// The released runtimegrpc adapter cannot produce refresh-only
			// credentials: it validates the grant-specific semantic response and
			// requires exactly one access credential before returning. A direct
			// test double can bypass that adapter, but L1 has no refresh-token
			// revocation authority. Keep the credential undisclosed and report
			// only the sanitized contract-invariant marker.
			log.Printf("sfcrm client-credentials Runtime response rejected: category=REFRESH_WITHOUT_ACCESS")
		}
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization server error")
		return
	}
	if response.Token == nil || issued.AccessToken == "" {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization server error")
		return
	}
	writer.Header().Set("Cache-Control", "no-store")
	writer.Header().Set("Pragma", "no-cache")
	body := map[string]any{"access_token": issued.AccessToken, "token_type": response.Token.TokenType, "expires_in": response.Token.ExpiresInSecond}
	if issued.RefreshToken != "" {
		body["refresh_token"] = issued.RefreshToken
	}
	body["instance_url"] = requestPublicOrigin(request)
	body["issued_at"] = fmt.Sprintf("%d", time.Now().UnixMilli())
	if response.Token.Scope != "" {
		body["scope"] = response.Token.Scope
	}
	if grantType != "client_credentials" {
		writeOAuthJSON(writer, http.StatusOK, body)
		return
	}
	if err := writeOAuthJSONChecked(writer, http.StatusOK, body); err != nil {
		if rollbackErr := s.rollbackAuthorizationAccessToken(request, issued.AccessToken); rollbackErr != nil {
			logClientCredentialsRollbackFailure(rollbackErr)
		}
	}
}

func (s *sessionHTTP) rollbackAuthorizationAccessToken(request *http.Request, accessToken string) error {
	rollbackContext, cancel := context.WithTimeout(context.WithoutCancel(request.Context()), clientCredentialsRollbackTimeout)
	defer cancel()
	var rollbackErr error
	for attempt := 0; attempt < clientCredentialsRollbackAttempts; attempt++ {
		if attempt > 0 {
			timer := time.NewTimer(time.Duration(attempt) * clientCredentialsRollbackBackoff)
			select {
			case <-timer.C:
			case <-rollbackContext.Done():
				timer.Stop()
				return rollbackContext.Err()
			}
		}
		rollbackErr = s.revoke(rollbackContext, runtimegrpc.SessionPresentedCredentials{AccessToken: accessToken}, sessionsemantic.RevokeRequest{})
		if rollbackErr == nil {
			return nil
		}
	}
	return rollbackErr
}

func logClientCredentialsRollbackFailure(err error) {
	category := "UNCLASSIFIED"
	var failure *sessionsemantic.Failure
	if errors.As(err, &failure) && sessionsemantic.ValidTopLevelFailure(failure.Category) {
		category = string(failure.Category)
	} else if errors.Is(err, context.DeadlineExceeded) {
		category = "DEADLINE_EXCEEDED"
	} else if errors.Is(err, context.Canceled) {
		category = "CANCELED"
	}
	log.Printf("sfcrm client-credentials session rollback failed: category=%s", category)
}

// requestPublicOrigin preserves the public OAuth issuer check across the L1/L0
// boundary. Forwarded origin is accepted only from a local/private reverse
// proxy; otherwise an external client could choose the issuer by sending proxy
// headers. Runtime compares this live origin with its canonical issuer.
func requestPublicOrigin(request *http.Request) string {
	if request == nil {
		return ""
	}
	scheme := "http"
	if request.TLS != nil {
		scheme = "https"
	}
	host := strings.TrimSpace(request.Host)
	if trustedPrivateProxy(request.RemoteAddr) {
		if forwarded := firstForwardedHeader(request.Header.Get("X-Forwarded-Proto")); forwarded != "" {
			scheme = forwarded
		}
		if forwarded := firstForwardedHeader(request.Header.Get("X-Forwarded-Host")); forwarded != "" {
			host = forwarded
		}
	}
	if host == "" {
		return ""
	}
	return strings.ToLower(strings.TrimSpace(scheme)) + "://" + strings.ToLower(host)
}

func trustedPrivateProxy(remoteAddress string) bool {
	host, _, err := net.SplitHostPort(strings.TrimSpace(remoteAddress))
	if err != nil {
		host = strings.TrimSpace(remoteAddress)
	}
	ip := net.ParseIP(strings.Trim(host, "[]"))
	return ip != nil && (ip.IsLoopback() || ip.IsPrivate())
}

func firstForwardedHeader(value string) string {
	if comma := strings.IndexByte(value, ','); comma >= 0 {
		value = value[:comma]
	}
	return strings.TrimSpace(value)
}

func (s *sessionHTTP) writeAuthorizationProtocolError(writer http.ResponseWriter, protocol *authorizationsemantic.ProtocolError) {
	if protocol == nil {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization server error")
		return
	}
	if protocol.TrustedRedirectURI != "" {
		writer.Header().Set("Location", buildAuthorizationRedirect(protocol.TrustedRedirectURI, "", protocol.Code, protocol.SafeDescription, protocol.State))
		writer.WriteHeader(http.StatusFound)
		return
	}
	writeOAuthError(writer, authorizationProtocolHTTPStatus(protocol.Code), protocol.Code, protocol.SafeDescription)
}

func authorizationProtocolHTTPStatus(code string) int {
	if code == "access_denied" {
		return http.StatusForbidden
	}
	return http.StatusBadRequest
}

func writeAuthorizationRuntimeFailure(writer http.ResponseWriter, err error) {
	var failure *authorizationsemantic.Failure
	if !errors.As(err, &failure) {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization service failed")
		return
	}
	switch failure.Category {
	case authorizationsemantic.FailureInvalidRequest:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid authorization request")
	case authorizationsemantic.FailureUnauthenticated:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_client", "client authentication failed")
	case authorizationsemantic.FailureForbidden:
		writeOAuthError(writer, http.StatusForbidden, "access_denied", "authorization is not permitted")
	case authorizationsemantic.FailureCanceled, authorizationsemantic.FailureDeadlineExceeded,
		authorizationsemantic.FailureStaleState, authorizationsemantic.FailureUnavailable:
		writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "authorization service temporarily unavailable")
	default:
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "authorization service failed")
	}
}

func buildAuthorizationRedirect(base, code, errorCode, description, state string) string {
	parsed, err := url.Parse(base)
	if err != nil {
		return base
	}
	query := parsed.Query()
	if code != "" {
		query.Set("code", code)
	}
	if errorCode != "" {
		query.Set("error", errorCode)
	}
	if description != "" {
		query.Set("error_description", description)
	}
	if state != "" {
		query.Set("state", state)
	}
	parsed.RawQuery = query.Encode()
	return parsed.String()
}

func (s *sessionHTTP) servePasswordToken(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodPost {
		writeOAuthMethodNotAllowed(writer, http.MethodPost)
		return
	}
	form, ok := parseOAuthForm(writer, request)
	if !ok {
		return
	}
	switch form.Get("grant_type") {
	case "authorization_code", "refresh_token", "client_credentials":
		s.serveAuthorizationExchange(writer, request, form)
		return
	case "password":
	default:
		writeOAuthError(writer, http.StatusBadRequest, "unsupported_grant_type", "unsupported grant type")
		return
	}
	username, password, clientID := form.Get("username"), form.Get("password"), form.Get("client_id")
	if username == "" || password == "" || clientID == "" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "username, password and client_id are required")
		return
	}
	if !s.passwordEnabled {
		if _, allowed := s.breakGlass[strings.ToLower(strings.TrimSpace(username))]; !allowed {
			writeOAuthError(writer, http.StatusBadRequest, "unauthorized_client", "password grant is disabled")
			return
		}
	}
	if sessionControlRejected(request) ||
		(s.browserSessionControlRequired(request, clientID) &&
			!apihostmiddleware.SessionControlRequestAdmitted(request.Context())) {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "browser session-control admission failed")
		return
	}
	password += form.Get("security_token")
	response, issued, err := s.create(request.Context(), runtimegrpc.SessionCreateCredentials{
		Identity: username, Secret: password, ClientSecret: form.Get("client_secret"),
	}, sessionsemantic.CreateRequest{
		Method:              sessionsemantic.AuthenticationMethodPassword,
		ApplicationClientID: clientID, RequestedScope: form.Get("scope"),
		SourceAddress: sourceAddress(request), UserAgent: request.UserAgent(),
		IssueControlProof: apihostmiddleware.SessionControlRequestAdmitted(request.Context()),
	})
	if err != nil {
		writeSessionOAuthFailure(writer, err)
		return
	}
	s.writeCreatedSession(writer, request, response, issued)
}

func (s *sessionHTTP) serveGoogleToken(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodPost {
		writeOAuthMethodNotAllowed(writer, http.MethodPost)
		return
	}
	if s.exchange == nil {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "Google SSO not configured")
		return
	}
	if sessionControlRejected(request) ||
		(s.requireBrowserControl && !apihostmiddleware.SessionControlRequestAdmitted(request.Context())) {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "browser session-control admission failed")
		return
	}
	code, redirectURI, state, ok := parseGoogleTokenRequest(writer, request)
	if !ok {
		return
	}
	if redirectURI != s.publicOrigin+"/oauth/callback" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "redirect_uri is not allowed")
		return
	}
	if strings.TrimSpace(state) == "" {
		if s.requireFederatedState {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_grant", "login state is invalid or expired; start the sign-in again")
			return
		}
	} else if !s.requireFederatedState && isPreUpgradeBrowserGoogleState(state) {
		// Before the server-owned protocol, the browser generated and validated
		// google:<UUID> locally. No Runtime transaction exists to consume. Admit
		// that exact historical shape only while the explicit rollout fence is
		// open; strict mode deliberately sends it through Runtime and rejects it.
	} else if err := s.consumeFederatedLogin(request.Context(), federatedloginsemantic.ConsumeRequest{
		State: canonicalRuntimeFederatedLoginState(state), RedirectURI: redirectURI,
	}); err != nil {
		writeFederatedLoginConsumeFailure(writer, err)
		return
	}
	idToken, err := s.exchange(request.Context(), code, redirectURI)
	if err != nil {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_grant", "Google authorization code exchange failed")
		return
	}
	response, issued, err := s.create(request.Context(), runtimegrpc.SessionCreateCredentials{Secret: idToken}, sessionsemantic.CreateRequest{
		Method:              sessionsemantic.AuthenticationMethodFederatedIDToken,
		FederatedProviderID: "google", SourceAddress: sourceAddress(request),
		UserAgent:         request.UserAgent(),
		IssueControlProof: apihostmiddleware.SessionControlRequestAdmitted(request.Context()),
	})
	if err != nil {
		writeSessionOAuthFailure(writer, err)
		return
	}
	s.writeCreatedSession(writer, request, response, issued)
}

func isPreUpgradeBrowserGoogleState(state string) bool {
	identifier, found := strings.CutPrefix(state, "google:")
	if !found || len(identifier) != 36 {
		return false
	}
	for index := range identifier {
		character := identifier[index]
		if index == 8 || index == 13 || index == 18 || index == 23 {
			if character != '-' {
				return false
			}
			continue
		}
		if !((character >= '0' && character <= '9') ||
			(character >= 'a' && character <= 'f') ||
			(character >= 'A' && character <= 'F')) {
			return false
		}
	}
	return true
}

func canonicalRuntimeFederatedLoginState(state string) string {
	const legacyPrefix = "ssologin."
	entropy, found := strings.CutPrefix(state, legacyPrefix)
	if !found {
		return state
	}
	decoded, err := base64.URLEncoding.DecodeString(entropy)
	if err != nil || len(decoded) != federatedloginsemantic.StateEntropyBytes ||
		base64.URLEncoding.EncodeToString(decoded) != entropy {
		return state
	}
	return base64.RawURLEncoding.EncodeToString(decoded)
}

func (s *sessionHTTP) serveGoogleLoginState(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodPost {
		writeOAuthMethodNotAllowed(writer, http.MethodPost)
		return
	}
	redirectURI, ok := parseGoogleLoginStateRequest(writer, request)
	if !ok {
		return
	}
	if redirectURI != s.publicOrigin+"/oauth/callback" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "redirect_uri is not allowed")
		return
	}
	if s.exchange == nil || s.beginFederatedLogin == nil || s.consumeFederatedLogin == nil {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "Google SSO not configured")
		return
	}
	response, err := s.beginFederatedLogin(request.Context(), federatedloginsemantic.BeginRequest{RedirectURI: redirectURI})
	if err != nil {
		writeFederatedLoginBeginFailure(writer, err)
		return
	}
	writer.Header().Set("Cache-Control", "no-store")
	writer.Header().Set("Pragma", "no-cache")
	writeOAuthJSON(writer, http.StatusOK, map[string]string{
		"state":      response.State,
		"expires_at": time.Unix(response.ExpiresAtUnixSecond, 0).UTC().Format(time.RFC3339),
	})
}

func (s *sessionHTTP) writeCreatedSession(
	writer http.ResponseWriter,
	request *http.Request,
	response sessionsemantic.CreateResponse,
	issued runtimegrpc.SessionIssuedCredentials,
) {
	if issued.AccessToken == "" {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "failed to establish session")
		return
	}
	if response.ControlProofIssued {
		if issued.ControlProof == "" || apihostmiddleware.IssueSessionControlResponse(
			request.Context(), issued.ControlProof, time.Unix(response.Session.ExpiresAtUnixSecond, 0),
		) != nil {
			_ = s.revoke(request.Context(), runtimegrpc.SessionPresentedCredentials{
				AccessToken: issued.AccessToken, ControlProof: issued.ControlProof,
			}, sessionsemantic.RevokeRequest{UseControlProof: issued.ControlProof != ""})
			writeOAuthError(writer, http.StatusInternalServerError, "server_error", "failed to establish browser session")
			return
		}
	}
	writer.Header().Set("Cache-Control", "no-store")
	writer.Header().Set("Pragma", "no-cache")
	writeOAuthJSON(writer, http.StatusOK, map[string]any{
		"access_token": issued.AccessToken,
		"instance_url": s.publicOrigin,
		"token_type":   "Bearer",
		"issued_at":    fmt.Sprintf("%d", time.Now().UnixMilli()),
	})
}

func (s *sessionHTTP) serveUserInfo(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodGet {
		writeOAuthMethodNotAllowed(writer, http.MethodGet)
		return
	}
	response, bearer, ok := s.readRequestSession(writer, request)
	if !ok {
		return
	}
	permissions, err := s.readEffective(request.Context(), bearer, systemPermissionAuthorityRequest())
	if err != nil {
		writeRuntimeFailure(writer, err)
		return
	}
	systemPermissions := make(map[string]bool, len(permissions.SystemPermissions))
	for _, permission := range permissions.SystemPermissions {
		systemPermissions[permission.PermissionID] = permission.Granted
	}
	principal := response.Session.Principal
	roleID := any(nil)
	if principal.RoleID != "" {
		roleID = principal.RoleID
	}
	base := s.publicOrigin
	writer.Header().Set("Cache-Control", "private, max-age=60")
	writer.Header().Set("Vary", "Authorization")
	writeOAuthJSON(writer, http.StatusOK, map[string]any{
		"sub":                base + "/id/" + s.organizationID + "/" + principal.PrincipalID,
		"user_id":            principal.PrincipalID,
		"organization_id":    s.organizationID,
		"preferred_username": principal.Email,
		"nickname":           principal.DisplayName,
		"name":               principal.DisplayName,
		"email":              principal.Email,
		"email_verified":     true,
		"profile_id":         principal.ProfileID,
		"role_id":            roleID,
		"is_active":          true,
		"permissions":        systemPermissions,
		"urls": map[string]string{
			"enterprise": base + "/services/Soap/c/63.0/" + s.organizationID,
			"rest":       base + "/services/data/v63.0/",
			"sobjects":   base + "/services/data/v63.0/sobjects/",
			"query":      base + "/services/data/v63.0/query/",
			"search":     base + "/services/data/v63.0/search/",
			"profile":    base + "/005/" + principal.PrincipalID,
		},
	})
}

func (s *sessionHTTP) serveRevoke(writer http.ResponseWriter, request *http.Request) {
	if request.Method != http.MethodPost {
		writeOAuthMethodNotAllowed(writer, http.MethodPost)
		return
	}
	form, ok := parseOAuthForm(writer, request)
	if !ok {
		return
	}
	if sessionControlRejected(request) {
		writer.WriteHeader(http.StatusOK)
		return
	}
	token := form.Get("token")
	if token == "" {
		token = request.URL.Query().Get("token")
	}
	if token == "" {
		writer.WriteHeader(http.StatusOK)
		return
	}
	proof, controlled := apihostmiddleware.SessionControlProof(request.Context())
	err := s.revoke(request.Context(), runtimegrpc.SessionPresentedCredentials{
		AccessToken: token, ControlProof: proof,
	}, sessionsemantic.RevokeRequest{UseControlProof: controlled})
	if err != nil && controlled {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "failed to revoke browser session")
		return
	}
	if controlled {
		if err := apihostmiddleware.ClearSessionControlResponse(request.Context()); err != nil {
			writeOAuthError(writer, http.StatusInternalServerError, "server_error", "failed to clear browser session")
			return
		}
	}
	writer.WriteHeader(http.StatusOK)
}

func (s *sessionHTTP) prepareControlledRequest(writer http.ResponseWriter, request *http.Request) bool {
	if !apihostmiddleware.SessionControlRequestAttempted(request.Context()) {
		return true
	}
	if !apihostmiddleware.SessionControlRequestAdmitted(request.Context()) {
		writeCRMError(writer, http.StatusUnauthorized, "INVALID_SESSION_ID", "Session expired or invalid")
		return false
	}
	_, bearer, ok := s.readRequestSession(writer, request)
	if ok {
		request.Header.Set("Authorization", "Bearer "+bearer)
	}
	return ok
}

func (s *sessionHTTP) readRequestSession(w http.ResponseWriter, r *http.Request) (sessionsemantic.ReadResponse, string, bool) {
	return s.readRequestSessionWithPolicy(w, r, nil)
}

func (s *sessionHTTP) readRequestSessionWithPolicy(
	writer http.ResponseWriter,
	request *http.Request,
	documentPolicy *sessionsemantic.DocumentPolicyRequest,
) (sessionsemantic.ReadResponse, string, bool) {
	bearer, ok := endUserBearer(request.Header.Values("Authorization"))
	if !ok {
		writeCRMError(writer, http.StatusUnauthorized, "INVALID_SESSION_ID", "Session expired or invalid")
		return sessionsemantic.ReadResponse{}, "", false
	}
	proof, controlled := apihostmiddleware.SessionControlProof(request.Context())
	if apihostmiddleware.SessionControlRequestAttempted(request.Context()) && !controlled {
		writeCRMError(writer, http.StatusUnauthorized, "INVALID_SESSION_ID", "Session expired or invalid")
		return sessionsemantic.ReadResponse{}, "", false
	}
	response, issued, err := s.read(request.Context(), runtimegrpc.SessionPresentedCredentials{
		AccessToken: bearer, ControlProof: proof,
	}, sessionsemantic.ReadRequest{AllowRenewal: controlled, UseControlProof: controlled, DocumentPolicy: documentPolicy})
	if err != nil {
		writeSessionCRMFailure(writer, err)
		return sessionsemantic.ReadResponse{}, "", false
	}
	if documentPolicy != nil && response.DocumentPolicy == nil {
		writeSessionCRMFailure(writer, &sessionsemantic.Failure{Category: sessionsemantic.FailureUnavailable})
		return sessionsemantic.ReadResponse{}, "", false
	}
	if response.ReplacementAccessTokenIssued {
		// Runtime rotates only the bearer. The independent browser proof remains
		// the same durable verifier and is reissued solely to align its cookie
		// expiry with the renewed Runtime-owned session.
		if issued.AccessToken == "" || issued.ControlProof != "" || proof == "" ||
			apihostmiddleware.IssueRenewedSessionResponse(
				request.Context(), issued.AccessToken, proof,
				time.Unix(response.ControlProofExpiresAtUnixSecond, 0),
			) != nil {
			writeCRMError(writer, http.StatusInternalServerError, "UNKNOWN_EXCEPTION", "Failed to renew session")
			return sessionsemantic.ReadResponse{}, "", false
		}
		bearer = issued.AccessToken
	}
	return response, bearer, true
}

func sessionControlRejected(request *http.Request) bool {
	return apihostmiddleware.SessionControlRequestAttempted(request.Context()) &&
		!apihostmiddleware.SessionControlRequestAdmitted(request.Context())
}

func (s *sessionHTTP) browserSessionControlRequired(request *http.Request, clientID string) bool {
	if s == nil || !s.requireBrowserControl {
		return false
	}
	if clientID == browserSessionClientID {
		return true
	}
	// Origin and Sec-Fetch-* are controlled by the browser rather than page
	// JavaScript. A browser therefore cannot evade the controlled-session path
	// by substituting another valid OAuth client ID. Non-browser OAuth clients
	// remain distinguishable because they need not send browser transport
	// metadata.
	return request != nil &&
		(request.Header.Get("Origin") != "" || request.Header.Get("Sec-Fetch-Site") != "")
}

func sourceAddress(request *http.Request) string {
	if request == nil {
		return ""
	}
	host, _, err := net.SplitHostPort(request.RemoteAddr)
	if err == nil {
		return host
	}
	return request.RemoteAddr
}

// NewGoogleCodeExchange builds the fixed-provider L1 authorization-code
// exchange. It returns only the signed ID token; Runtime independently verifies
// issuer, audience, signature, expiry, and verified identity before creating a
// durable session.
func NewGoogleCodeExchange(client *http.Client, clientID, clientSecret string) (FederatedCodeExchangeFunc, error) {
	if client == nil || client.Timeout <= 0 || strings.TrimSpace(clientID) == "" ||
		strings.TrimSpace(clientSecret) == "" || strings.TrimSpace(clientID) != clientID ||
		strings.TrimSpace(clientSecret) != clientSecret {
		return nil, errors.New("sfcrm AppService: bounded Google client and credentials are required")
	}
	boundedClient := *client
	// The token request carries the configured client secret. Never permit an
	// HTTP 307/308 response to replay that POST body to another origin.
	boundedClient.CheckRedirect = func(*http.Request, []*http.Request) error {
		return http.ErrUseLastResponse
	}
	return func(ctx context.Context, code, redirectURI string) (string, error) {
		form := url.Values{
			"code": {code}, "client_id": {clientID}, "client_secret": {clientSecret},
			"redirect_uri": {redirectURI}, "grant_type": {"authorization_code"},
		}
		request, err := http.NewRequestWithContext(
			ctx, http.MethodPost, "https://oauth2.googleapis.com/token", strings.NewReader(form.Encode()),
		)
		if err != nil {
			return "", errors.New("build Google token request")
		}
		request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		response, err := boundedClient.Do(request)
		if err != nil {
			return "", errors.New("Google token service unavailable")
		}
		defer response.Body.Close()
		if response.StatusCode < 200 || response.StatusCode >= 300 {
			_, _ = io.Copy(io.Discard, io.LimitReader(response.Body, 1<<20))
			return "", errors.New("Google token exchange rejected")
		}
		body, err := io.ReadAll(io.LimitReader(response.Body, (1<<20)+1))
		if err != nil || len(body) > 1<<20 {
			return "", errors.New("Google token response exceeded the size limit")
		}
		decoder := json.NewDecoder(strings.NewReader(string(body)))
		var token struct {
			IDToken string `json:"id_token"`
		}
		if err := decoder.Decode(&token); err != nil || decoder.Decode(&struct{}{}) != io.EOF ||
			strings.TrimSpace(token.IDToken) == "" || strings.TrimSpace(token.IDToken) != token.IDToken ||
			len(token.IDToken) > 64*1024 {
			return "", errors.New("Google token response did not contain an ID token")
		}
		return token.IDToken, nil
	}, nil
}

func parseOAuthForm(writer http.ResponseWriter, request *http.Request) (url.Values, bool) {
	request.Body = http.MaxBytesReader(writer, request.Body, maxOAuthRequestBytes)
	if err := request.ParseForm(); err != nil {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid form body")
		return nil, false
	}
	for _, name := range []string{
		"grant_type", "username", "password", "security_token", "client_id", "client_secret", "scope", "token",
		"code", "redirect_uri", "code_verifier", "refresh_token", "resource", "continue",
	} {
		if len(request.PostForm[name]) > 1 {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "duplicate form parameter")
			return nil, false
		}
	}
	return request.PostForm, true
}

func parseGoogleLoginStateRequest(writer http.ResponseWriter, request *http.Request) (string, bool) {
	request.Body = http.MaxBytesReader(writer, request.Body, maxOAuthRequestBytes)
	var redirectURI string
	if strings.Contains(strings.ToLower(request.Header.Get("Content-Type")), "application/json") {
		var body struct {
			RedirectURI string `json:"redirect_uri"`
		}
		decoder := json.NewDecoder(request.Body)
		decoder.DisallowUnknownFields()
		if err := decoder.Decode(&body); err != nil || decoder.Decode(&struct{}{}) != io.EOF {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid JSON body")
			return "", false
		}
		redirectURI = body.RedirectURI
	} else {
		if err := request.ParseForm(); err != nil {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid form body")
			return "", false
		}
		if len(request.PostForm["redirect_uri"]) > 1 {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "duplicate form parameter")
			return "", false
		}
		redirectURI = request.PostForm.Get("redirect_uri")
	}
	if redirectURI == "" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "redirect_uri is required")
		return "", false
	}
	return redirectURI, true
}

func parseGoogleTokenRequest(writer http.ResponseWriter, request *http.Request) (string, string, string, bool) {
	request.Body = http.MaxBytesReader(writer, request.Body, maxOAuthRequestBytes)
	var code, redirectURI, state string
	if strings.Contains(strings.ToLower(request.Header.Get("Content-Type")), "application/json") {
		var body struct {
			Code        string `json:"code"`
			RedirectURI string `json:"redirect_uri"`
			State       string `json:"state"`
		}
		decoder := json.NewDecoder(request.Body)
		decoder.DisallowUnknownFields()
		if err := decoder.Decode(&body); err != nil || decoder.Decode(&struct{}{}) != io.EOF {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid JSON body")
			return "", "", "", false
		}
		code, redirectURI, state = body.Code, body.RedirectURI, body.State
	} else {
		if err := request.ParseForm(); err != nil {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid form body")
			return "", "", "", false
		}
		if len(request.PostForm["code"]) > 1 || len(request.PostForm["redirect_uri"]) > 1 || len(request.PostForm["state"]) > 1 {
			writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "duplicate form parameter")
			return "", "", "", false
		}
		code, redirectURI, state = request.PostForm.Get("code"), request.PostForm.Get("redirect_uri"), request.PostForm.Get("state")
	}
	if code == "" || redirectURI == "" {
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "code and redirect_uri are required")
		return "", "", "", false
	}
	return code, redirectURI, state, true
}

func writeFederatedLoginBeginFailure(writer http.ResponseWriter, err error) {
	var failure *federatedloginsemantic.Failure
	if !errors.As(err, &failure) {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "sign-in is temporarily unavailable")
		return
	}
	switch failure.Category {
	case federatedloginsemantic.FailureInvalidRequest:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid login initialization request")
	case federatedloginsemantic.FailureCanceled, federatedloginsemantic.FailureDeadlineExceeded,
		federatedloginsemantic.FailureStaleState, federatedloginsemantic.FailureUnavailable,
		federatedloginsemantic.FailureResourceExhausted:
		writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "sign-in is temporarily unavailable")
	default:
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "sign-in is temporarily unavailable")
	}
}

func writeFederatedLoginConsumeFailure(writer http.ResponseWriter, err error) {
	var failure *federatedloginsemantic.Failure
	if !errors.As(err, &failure) {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "sign-in is temporarily unavailable")
		return
	}
	switch failure.Category {
	case federatedloginsemantic.FailureInvalidRequest, federatedloginsemantic.FailureUnauthenticated:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_grant", "login state is invalid or expired; start the sign-in again")
	case federatedloginsemantic.FailureCanceled, federatedloginsemantic.FailureDeadlineExceeded,
		federatedloginsemantic.FailureStaleState, federatedloginsemantic.FailureUnavailable,
		federatedloginsemantic.FailureResourceExhausted:
		writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "sign-in is temporarily unavailable")
	default:
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "sign-in is temporarily unavailable")
	}
}

func writeSessionOAuthFailure(writer http.ResponseWriter, err error) {
	logSessionRuntimeFailure("create", err)
	var failure *sessionsemantic.Failure
	if !errors.As(err, &failure) {
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "session service failed")
		return
	}
	switch failure.Category {
	case sessionsemantic.FailureInvalidRequest:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_request", "invalid session request")
	case sessionsemantic.FailureUnauthenticated:
		writeOAuthError(writer, http.StatusBadRequest, "invalid_grant", "authentication failure")
	case sessionsemantic.FailureForbidden:
		writeOAuthError(writer, http.StatusForbidden, "access_denied", "user is not authorized for this application")
	case sessionsemantic.FailureStaleState, sessionsemantic.FailureUnavailable,
		sessionsemantic.FailureCanceled, sessionsemantic.FailureDeadlineExceeded,
		sessionsemantic.FailureResourceExhausted:
		writeOAuthError(writer, http.StatusServiceUnavailable, "temporarily_unavailable", "session service temporarily unavailable")
	default:
		writeOAuthError(writer, http.StatusInternalServerError, "server_error", "session service failed")
	}
}

func writeSessionCRMFailure(writer http.ResponseWriter, err error) {
	logSessionRuntimeFailure("read", err)
	var failure *sessionsemantic.Failure
	if errors.As(err, &failure) {
		switch failure.Category {
		case sessionsemantic.FailureUnauthenticated, sessionsemantic.FailureForbidden:
			writeCRMError(writer, http.StatusUnauthorized, "INVALID_SESSION_ID", "Session expired or invalid")
			return
		case sessionsemantic.FailureStaleState, sessionsemantic.FailureUnavailable,
			sessionsemantic.FailureCanceled, sessionsemantic.FailureDeadlineExceeded,
			sessionsemantic.FailureResourceExhausted:
			writeCRMError(writer, http.StatusServiceUnavailable, "UNKNOWN_EXCEPTION", "Session service temporarily unavailable")
			return
		}
	}
	writeCRMError(writer, http.StatusInternalServerError, "UNKNOWN_EXCEPTION", "Session service failed")
}

func logSessionRuntimeFailure(operation string, err error) {
	var failure *sessionsemantic.Failure
	if !errors.As(err, &failure) || !sessionsemantic.ValidTopLevelFailure(failure.Category) {
		log.Printf("sfcrm session runtime failure: operation=%s category=UNCLASSIFIED", operation)
		return
	}
	switch failure.Category {
	case sessionsemantic.FailureCanceled,
		sessionsemantic.FailureDeadlineExceeded,
		sessionsemantic.FailureResourceExhausted,
		sessionsemantic.FailureIncompatible,
		sessionsemantic.FailureStaleState,
		sessionsemantic.FailureUnavailable,
		sessionsemantic.FailureInternal:
		log.Printf(
			"sfcrm session runtime failure: operation=%s category=%s stale_axis=%s required_revision=%d served_revision=%d limit_kind=%s maximum=%d retry_after_ms=%d request_id=%s",
			operation,
			failure.Category,
			sessionLogToken(string(failure.StaleAxis)),
			failure.RequiredRevision,
			failure.ServedRevision,
			sessionLogToken(string(failure.LimitKind)),
			failure.Maximum,
			failure.RetryAfterMillis,
			sessionLogToken(failure.RequestID),
		)
	}
}

func sessionLogToken(value string) string {
	if value == "" {
		return "-"
	}
	if len(value) > 128 {
		return "INVALID"
	}
	for _, character := range value {
		if (character >= 'a' && character <= 'z') ||
			(character >= 'A' && character <= 'Z') ||
			(character >= '0' && character <= '9') ||
			strings.ContainsRune("-_.:/", character) {
			continue
		}
		return "INVALID"
	}
	return value
}

func writeOAuthMethodNotAllowed(writer http.ResponseWriter, method string) {
	writer.Header().Set("Allow", method)
	writeOAuthError(writer, http.StatusMethodNotAllowed, "invalid_request", "method not allowed")
}

func writeOAuthError(writer http.ResponseWriter, status int, code, description string) {
	writeOAuthJSON(writer, status, map[string]string{"error": code, "error_description": description})
}

func writeOAuthJSON(writer http.ResponseWriter, status int, value any) {
	_ = writeOAuthJSONChecked(writer, status, value)
}

func writeOAuthJSONChecked(writer http.ResponseWriter, status int, value any) error {
	payload, err := json.Marshal(value)
	if err != nil {
		return err
	}
	payload = append(payload, '\n')
	writer.Header().Set("Content-Type", "application/json")
	writer.WriteHeader(status)
	_, err = writer.Write(payload)
	return err
}
