package sfcrmappservice

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"
	"sync/atomic"
	"testing"

	crmwire "github.com/pingcap-inc/nexuscrm-app-packs/sfcrm/wire"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/recordmutationv1"
)

func mutationReceipts() semantic.Receipts {
	return semantic.Receipts{
		ProtocolVersion: "1.0", CapabilityVersion: semantic.CapabilityName,
		CatalogRevision: 7, SchemaGeneration: 2, EngineGeneration: 3, SecurityEpoch: 5,
	}
}

func successfulMutationResponse(t *testing.T, request semantic.Request) semantic.Response {
	t.Helper()
	digest, err := semantic.CommandDigest(request)
	if err != nil {
		t.Fatal(err)
	}
	results := make([]semantic.OperationResult, len(request.Operations))
	created := true
	for i, operation := range request.Operations {
		recordID := operation.RecordID
		var createdValue *bool
		if operation.Kind == semantic.OperationCreate {
			recordID = "created-" + string(rune('1'+i))
			createdCopy := created
			createdValue = &createdCopy
		}
		results[i] = semantic.OperationResult{
			Index: uint32(i), Kind: operation.Kind, RecordID: recordID,
			Success: true, Created: createdValue, Errors: []semantic.OperationError{},
		}
	}
	return semantic.Response{
		CommandID: request.CommandID, CommandDigest: digest, Results: results,
		Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
	}
}

func TestRuntimeMutationClientMakesOneCoarseCallWithLosslessSourceValues(t *testing.T) {
	fields, err := mutationFields(map[string]any{
		"When": "2026-07-19T12:30:00Z", "Exact": json.Number("12345678901234567890.00100"),
		"False": false, "Empty": "", "Null": nil,
		"Payload": map[string]any{"z": json.Number("2"), "a": []any{json.Number("0"), false, ""}},
	}, false)
	if err != nil {
		t.Fatal(err)
	}
	var calls int
	var got semantic.Request
	client, err := NewRuntimeMutationClient(func(_ context.Context, bearer string, request semantic.Request) (semantic.Response, error) {
		calls++
		got = request
		if bearer != "user-secret" {
			t.Fatalf("bearer = %q", bearer)
		}
		return successfulMutationResponse(t, request), nil
	})
	if err != nil {
		t.Fatal(err)
	}
	client.newCommandID = func() (string, error) { return "sfcrm-command-1", nil }
	response, err := client.Mutate(testContext(t), "user-secret", "", semantic.MutationUseCaseSingle, semantic.BatchIndependent, []semantic.Operation{{
		Kind: semantic.OperationCreate, ObjectID: "Event", Fields: fields,
	}})
	if err != nil {
		t.Fatal(err)
	}
	if calls != 1 || response.Results[0].RecordID == "" || got.CommandID != "sfcrm-command-1" || got.UseCase != semantic.MutationUseCaseSingle {
		t.Fatalf("calls=%d request=%#v response=%#v", calls, got, response)
	}
	values := make(map[string]semantic.FieldValue)
	for _, field := range got.Operations[0].Fields {
		values[field.Name] = field
	}
	if values["When"].Kind != semantic.ValueKindString || *values["When"].String != "2026-07-19T12:30:00Z" ||
		values["Exact"].Kind != semantic.ValueKindNumber || *values["Exact"].Number != "12345678901234567890.00100" ||
		values["Payload"].Kind != semantic.ValueKindJSON || *values["Payload"].JSON != `{"a":[0,false,""],"z":2}` ||
		values["False"].Boolean == nil || *values["False"].Boolean || values["Empty"].String == nil || *values["Empty"].String != "" || !values["Null"].Null {
		t.Fatalf("lossless values = %#v", values)
	}
}

func TestServiceIdempotencyIdentitySurvivesAppServiceRestart(t *testing.T) {
	var commandIDs []string
	mutate := func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		commandIDs = append(commandIDs, request.CommandID)
		return successfulMutationResponse(t, request), nil
	}
	for range 2 {
		service, _ := newMutationService(t, mutate)
		request := mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Account", `{"Name":"Ada"}`)
		request.Header.Set(crmMutationIdempotencyHeader, "logical-create-42")
		recorder := httptest.NewRecorder()
		service.ServeHTTP(recorder, request)
		if recorder.Code != http.StatusCreated {
			t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
		}
	}
	if len(commandIDs) != 2 || commandIDs[0] != commandIDs[1] || commandIDs[0] == "logical-create-42" || !strings.HasPrefix(commandIDs[0], "sfcrm-idem-") {
		t.Fatalf("restart command identities = %#v", commandIDs)
	}
}

func TestServiceDistinguishesRuntimeAdmissionFromMutationRequestLimits(t *testing.T) {
	for _, test := range []struct {
		name           string
		failure        *semantic.Failure
		wantStatus     int
		wantRetryAfter string
		wantBody       string
	}{
		{
			name: "temporary runtime admission saturation",
			failure: &semantic.Failure{
				Category:         semantic.FailureResourceExhausted,
				LimitKind:        semantic.LimitAdmission,
				Maximum:          16,
				RetryAfterMillis: 50,
			},
			wantStatus:     http.StatusServiceUnavailable,
			wantRetryAfter: "1",
			wantBody:       `[{"errorCode":"UNKNOWN_EXCEPTION","message":"Service temporarily unavailable"}]` + "\n",
		},
		{
			name: "admission without retry instruction",
			failure: &semantic.Failure{
				Category:  semantic.FailureResourceExhausted,
				LimitKind: semantic.LimitAdmission,
				Maximum:   16,
			},
			wantStatus: http.StatusServiceUnavailable,
			wantBody:   `[{"errorCode":"UNKNOWN_EXCEPTION","message":"Service temporarily unavailable"}]` + "\n",
		},
		{
			name: "non-retryable mutation request limit",
			failure: &semantic.Failure{
				Category:  semantic.FailureResourceExhausted,
				LimitKind: semantic.LimitSemanticRequest,
			},
			wantStatus: http.StatusBadRequest,
			wantBody:   `[{"errorCode":"LIMIT_EXCEEDED","message":"Request exceeds a supported limit"}]` + "\n",
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			var calls atomic.Uint64
			service, _ := newMutationService(t, func(context.Context, string, semantic.Request) (semantic.Response, error) {
				calls.Add(1)
				return semantic.Response{}, test.failure
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(
				http.MethodPost,
				"/services/data/v63.0/sobjects/Account",
				`{"Name":"Staging Inspection AI Account"}`,
			))
			if calls.Load() != 1 || recorder.Code != test.wantStatus ||
				recorder.Header().Get("Retry-After") != test.wantRetryAfter ||
				recorder.Body.String() != test.wantBody {
				t.Fatalf(
					"calls=%d status=%d retry-after=%q body=%s",
					calls.Load(), recorder.Code,
					recorder.Header().Get("Retry-After"), recorder.Body.String(),
				)
			}
		})
	}
}

func TestServiceRejectsAmbiguousIdempotencyIdentityBeforeRuntime(t *testing.T) {
	var calls atomic.Uint64
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		calls.Add(1)
		return successfulMutationResponse(t, request), nil
	})
	for _, values := range [][]string{{""}, {" not-canonical"}, {"one", "two"}} {
		request := mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Account", `{}`)
		request.Header[crmMutationIdempotencyHeader] = values
		recorder := httptest.NewRecorder()
		service.ServeHTTP(recorder, request)
		if recorder.Code != http.StatusBadRequest {
			t.Fatalf("values=%q status=%d body=%s", values, recorder.Code, recorder.Body.String())
		}
	}
	if calls.Load() != 0 {
		t.Fatalf("ambiguous idempotency identities reached Runtime %d times", calls.Load())
	}
}

func newMutationService(t *testing.T, mutate RuntimeMutateFunc) (*Service, *fakeRuntime) {
	t.Helper()
	runtime := &fakeRuntime{}
	runtime.ready.Store(true)
	service := newTestService(t, runtime)
	service.maxRequestBytes = 25 * 1024 * 1024
	mutation, err := NewRuntimeMutationClient(mutate)
	if err != nil {
		t.Fatal(err)
	}
	service.mutation = mutation
	return service, runtime
}

func mutationHTTPRequest(method, path, body string) *http.Request {
	request := httptest.NewRequest(method, path, strings.NewReader(body))
	request.Header.Set("Authorization", "Bearer user-secret")
	return request
}

func TestServiceProjectsSingleCreateWithoutMetadataOrDatabaseSideChannel(t *testing.T) {
	var calls atomic.Uint64
	var got semantic.Request
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		calls.Add(1)
		got = request
		return successfulMutationResponse(t, request), nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Opportunity", `{
		"Name":"", "Active":false, "Amount":0, "CloseDate":"2026-07-31", "Payload":{"b":1,"a":null}, "Optional":null
	}`))
	if recorder.Code != http.StatusCreated || calls.Load() != 1 || got.UseCase != semantic.MutationUseCaseSingle ||
		len(got.Operations) != 1 || got.Operations[0].ObjectID != "Opportunity" || got.Operations[0].Kind != semantic.OperationCreate {
		t.Fatalf("status=%d calls=%d request=%#v body=%s", recorder.Code, calls.Load(), got, recorder.Body.String())
	}
	var body map[string]any
	if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil || body["success"] != true || body["id"] != "created-1" {
		t.Fatalf("response=%#v err=%v", body, err)
	}
}

func TestServicePreservesExistingMutationJSONGrammar(t *testing.T) {
	for _, test := range []struct {
		name     string
		method   string
		path     string
		body     string
		wantCode string
		wantBody string
	}{
		{
			name: "single create", method: http.MethodPost,
			path: "/services/data/v63.0/sobjects/Account", body: `{`,
			wantCode: crmwire.SFCodeJSONParserError, wantBody: "Invalid JSON",
		},
		{
			name: "single update", method: http.MethodPatch,
			path: "/services/data/v63.0/sobjects/Account/001-test", body: `{`,
			wantCode: crmwire.SFCodeJSONParserError, wantBody: "unexpected EOF",
		},
		{
			name: "composite", method: http.MethodPost,
			path: "/services/data/v63.0/composite/sobjects", body: `{`,
			wantCode: crmwire.SFCodeInvalidRequest, wantBody: "Invalid request body",
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			var calls atomic.Uint64
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				calls.Add(1)
				return successfulMutationResponse(t, request), nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(test.method, test.path, test.body))
			want := `[{"errorCode":"` + test.wantCode + `","message":"` + test.wantBody + `"}]` + "\n"
			if recorder.Code != http.StatusBadRequest || recorder.Body.String() != want || calls.Load() != 0 {
				t.Fatalf("status=%d calls=%d body=%s, want %s", recorder.Code, calls.Load(), recorder.Body.String(), want)
			}
		})
	}
}

func TestServicePreservesExistingFirstJSONValueSemantics(t *testing.T) {
	for _, test := range []struct {
		name       string
		method     string
		path       string
		body       string
		wantStatus int
	}{
		{
			name: "single create", method: http.MethodPost,
			path: "/services/data/v63.0/sobjects/Account", body: `{"Name":"Ada"} trailing`, wantStatus: http.StatusCreated,
		},
		{
			name: "single update", method: http.MethodPatch,
			path: "/services/data/v63.0/sobjects/Account/001-test", body: `{"Name":"Ada"} trailing`, wantStatus: http.StatusNoContent,
		},
		{
			name: "composite", method: http.MethodPost,
			path: "/services/data/v63.0/composite/sobjects", body: `{"records":[{"attributes":{"type":"Account"},"Name":"Ada"}]} trailing`, wantStatus: http.StatusOK,
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			var calls atomic.Uint64
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				calls.Add(1)
				return successfulMutationResponse(t, request), nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(test.method, test.path, test.body))
			if recorder.Code != test.wantStatus || calls.Load() != 1 {
				t.Fatalf("status=%d calls=%d body=%s", recorder.Code, calls.Load(), recorder.Body.String())
			}
		})
	}
}

func TestServiceCountsTrailingInputAgainstCompleteRequestEnvelope(t *testing.T) {
	var calls atomic.Uint64
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		calls.Add(1)
		return successfulMutationResponse(t, request), nil
	})
	service.maxRequestBytes = int64(len(`{"Name":"Ada"}`) + 1)
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(
		http.MethodPost,
		"/services/data/v63.0/sobjects/Account",
		`{"Name":"Ada"} oversized-trailing-input`,
	))
	if recorder.Code != http.StatusBadRequest || calls.Load() != 0 {
		t.Fatalf("status=%d calls=%d body=%s", recorder.Code, calls.Load(), recorder.Body.String())
	}
}

func TestServiceCompositeUpdateIsOnePositionStableRuntimeCall(t *testing.T) {
	var requests []semantic.Request
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		requests = append(requests, request)
		return successfulMutationResponse(t, request), nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPatch, "/services/data/v59.0/composite/sobjects", `{
		"allOrNone":true,
		"records":[
			{"attributes":{"type":"Account"},"Id":"001-a","Name":"A"},
			{"attributes":{"type":"Contact"},"Id":"003-b","Active":false}
		]
	}`))
	if recorder.Code != http.StatusOK || len(requests) != 1 || requests[0].UseCase != semantic.MutationUseCaseCollection ||
		requests[0].BatchMode != semantic.BatchAtomic || len(requests[0].Operations) != 2 ||
		requests[0].Operations[0].RecordID != "001-a" || requests[0].Operations[1].ObjectID != "Contact" {
		t.Fatalf("status=%d requests=%#v body=%s", recorder.Code, requests, recorder.Body.String())
	}
	for _, operation := range requests[0].Operations {
		for _, field := range operation.Fields {
			if strings.EqualFold(field.Name, "Id") || strings.EqualFold(field.Name, "attributes") {
				t.Fatalf("L1 route metadata leaked into Runtime field assignments: %#v", operation.Fields)
			}
		}
	}
	var body []map[string]any
	if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil || len(body) != 2 || body[0]["id"] != "001-a" || body[1]["id"] != "003-b" {
		t.Fatalf("response=%#v err=%v", body, err)
	}
}

func TestServiceEmptyCompositeAndUninstalledMutationPortMakeZeroCalls(t *testing.T) {
	var mutationCalls atomic.Uint64
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		mutationCalls.Add(1)
		return successfulMutationResponse(t, request), nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/composite/sobjects", `{"records":[]}`))
	if recorder.Code != http.StatusOK || recorder.Body.String() != "[]\n" || mutationCalls.Load() != 0 {
		t.Fatalf("status=%d calls=%d body=%s", recorder.Code, mutationCalls.Load(), recorder.Body.String())
	}

	legacyRuntime := &fakeRuntime{}
	legacyRuntime.ready.Store(true)
	legacyOnly := newTestService(t, legacyRuntime)
	recorder = httptest.NewRecorder()
	legacyOnly.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Account", `{}`))
	if recorder.Code != http.StatusNotFound || legacyRuntime.calls.Load() != 0 {
		t.Fatalf("non-serving guard status=%d calls=%d", recorder.Code, legacyRuntime.calls.Load())
	}
}

func TestServiceOwnsProductMutationErrorCodeProjection(t *testing.T) {
	for _, test := range []struct {
		name     string
		kind     semantic.ErrorKind
		message  string
		fields   []string
		wantCode string
	}{
		{name: "policy", kind: semantic.ErrorPolicyDenied, message: "Creation is closed.", fields: []string{"State"}, wantCode: crmCodeInsertFailed},
		{name: "required", kind: semantic.ErrorRequiredFieldMissing, fields: []string{"Name"}, wantCode: crmCodeRequiredFieldMissing},
	} {
		t.Run(test.name, func(t *testing.T) {
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				digest, err := semantic.CommandDigest(request)
				if err != nil {
					t.Fatal(err)
				}
				return semantic.Response{
					CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
					Results: []semantic.OperationResult{{Index: 0, Kind: semantic.OperationCreate, Errors: []semantic.OperationError{{Kind: test.kind, AuthoredMessage: test.message, Fields: test.fields}}}},
				}, nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Account", `{}`))
			var errors []map[string]any
			if err := json.Unmarshal(recorder.Body.Bytes(), &errors); err != nil || recorder.Code != http.StatusBadRequest || len(errors) != 1 || errors[0]["errorCode"] != test.wantCode {
				t.Fatalf("status=%d errors=%#v err=%v body=%s", recorder.Code, errors, err, recorder.Body.String())
			}
		})
	}
}

func TestServiceKeepsPositionStableResultsForTransactionPolicyRecheck(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{
				{Index: 0, Kind: semantic.OperationUpdate, RecordID: "001-a", Success: true, Errors: []semantic.OperationError{}},
				{Index: 1, Kind: semantic.OperationUpdate, RecordID: "001-b", Success: false, Errors: []semantic.OperationError{{
					Kind: semantic.ErrorPolicyDenied, AuthoredMessage: "Updates are closed.", Fields: []string{"State"},
				}}},
			},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPatch, "/services/data/v63.0/composite/sobjects", `{
		"records":[
			{"attributes":{"type":"Account"},"Id":"001-a","Name":"first"},
			{"attributes":{"type":"Account"},"Id":"001-b","State":"Closed"}
		]
	}`))
	const want = `[{"errors":[],"id":"001-a","success":true},{"errors":[{"fields":["State"],"message":"Updates are closed.","statusCode":"INVALID_FIELD_FOR_INSERT_UPDATE"}],"id":"001-b","success":false}]` + "\n"
	if recorder.Code != http.StatusOK || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
	}
}

func TestServiceKeepsAtomicRollbackResultsForTransactionPolicyRecheck(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{
				{Index: 0, Kind: semantic.OperationUpdate, RecordID: "001-a", Success: false, Errors: []semantic.OperationError{{Kind: semantic.ErrorAtomicRolledBack, Fields: []string{}}}},
				{Index: 1, Kind: semantic.OperationUpdate, RecordID: "001-b", Success: false, Errors: []semantic.OperationError{{
					Kind: semantic.ErrorPolicyDenied, AuthoredMessage: "Updates are closed.", Fields: []string{"State"},
				}}},
			},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPatch, "/services/data/v63.0/composite/sobjects", `{
		"allOrNone":true,
		"records":[
			{"attributes":{"type":"Account"},"Id":"001-a","Name":"first"},
			{"attributes":{"type":"Account"},"Id":"001-b","State":"Closed"}
		]
	}`))
	const want = `[{"errors":[{"fields":[],"message":"Record rolled back because not all records were valid and the request was using AllOrNone header","statusCode":"ALL_OR_NONE_OPERATION_ROLLED_BACK"}],"id":"001-a","success":false},{"errors":[{"fields":["State"],"message":"Updates are closed.","statusCode":"INVALID_FIELD_FOR_INSERT_UPDATE"}],"id":"001-b","success":false}]` + "\n"
	if recorder.Code != http.StatusOK || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
	}
}

func TestServiceKeepsCommandPreflightPolicyDenialAsOneCRMError(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{
				{Index: 0, Kind: semantic.OperationUpdate, RecordID: "001-a", Success: false, Errors: []semantic.OperationError{{Kind: semantic.ErrorProcessingHalted, Fields: []string{}}}},
				{Index: 1, Kind: semantic.OperationUpdate, RecordID: "001-b", Success: false, Errors: []semantic.OperationError{{
					Kind: semantic.ErrorPolicyDenied, AuthoredMessage: "Updates are closed.", Fields: []string{"State"},
				}}},
			},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPatch, "/services/data/v63.0/composite/sobjects", `{
		"records":[
			{"attributes":{"type":"Account"},"Id":"001-a","Name":"first"},
			{"attributes":{"type":"Account"},"Id":"001-b","State":"Closed"}
		]
	}`))
	const want = `[{"errorCode":"INVALID_FIELD_FOR_INSERT_UPDATE","message":"Updates are closed.","fields":["State"]}]` + "\n"
	if recorder.Code != http.StatusBadRequest || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
	}
}

func TestServiceProjectsFieldAccessDenialToExistingCRMGrammar(t *testing.T) {
	const message = "Unable to create/update fields: Amount, Status. Please check the security settings of this field and verify that it is read/write for your profile or permission set."
	for _, test := range []struct {
		name       string
		path       string
		body       string
		wantStatus int
		wantBody   string
	}{
		{
			name:       "single",
			path:       "/services/data/v63.0/sobjects/Account",
			body:       `{"Amount":1,"Status":"Closed"}`,
			wantStatus: http.StatusBadRequest,
			wantBody:   `[{"errorCode":"INVALID_FIELD_FOR_INSERT_UPDATE","message":"` + message + `","fields":["Amount","Status"]}]` + "\n",
		},
		{
			name:       "composite",
			path:       "/services/data/v63.0/composite/sobjects",
			body:       `{"records":[{"attributes":{"type":"Account"},"Amount":1,"Status":"Closed"}]}`,
			wantStatus: http.StatusOK,
			wantBody:   `[{"errors":[{"fields":["Amount","Status"],"message":"` + message + `","statusCode":"INVALID_FIELD_FOR_INSERT_UPDATE"}],"id":"","success":false}]` + "\n",
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				digest, err := semantic.CommandDigest(request)
				if err != nil {
					t.Fatal(err)
				}
				return semantic.Response{
					CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
					Results: []semantic.OperationResult{{
						Index: 0, Kind: semantic.OperationCreate,
						Errors: []semantic.OperationError{{Kind: semantic.ErrorAccessDenied, Fields: []string{"Amount", "Status"}}},
					}},
				}, nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, test.path, test.body))
			if recorder.Code != test.wantStatus || recorder.Body.String() != test.wantBody {
				t.Fatalf("status=%d body=%s, want status=%d body=%s", recorder.Code, recorder.Body.String(), test.wantStatus, test.wantBody)
			}
		})
	}
}

func TestServiceDoesNotProjectFieldValueValidationAsFieldAccessDenial(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{{
				Index: 0, Kind: semantic.OperationUpdate, RecordID: "001-a",
				Errors: []semantic.OperationError{{Kind: semantic.ErrorFieldIntegrity, Fields: []string{"Website"}}},
			}},
		}, nil
	})

	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(
		http.MethodPatch,
		"/services/data/v63.0/sobjects/Account/001-a",
		`{"Website":"//invalid.example"}`,
	))
	const want = `[{"errorCode":"FIELD_INTEGRITY_EXCEPTION","message":"Field integrity exception","fields":["Website"]}]` + "\n"
	if recorder.Code != http.StatusBadRequest || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
	}
}

func TestObjectAccessDenialUsesEstablishedOperationScopedCRMGrammar(t *testing.T) {
	for _, test := range []struct {
		name string
		kind semantic.OperationKind
		want string
	}{
		{name: "create", kind: semantic.OperationCreate, want: "permission denied: cannot Create Credits_Topup__c"},
		{name: "update", kind: semantic.OperationUpdate, want: "permission denied: cannot Edit Credits_Topup__c"},
		{name: "delete", kind: semantic.OperationDelete, want: "permission denied: cannot Delete Credits_Topup__c"},
	} {
		t.Run(test.name, func(t *testing.T) {
			code, message := crmMutationErrorProjection(
				"v63.0",
				"Credits_Topup__c",
				test.kind,
				semantic.OperationError{
					Kind:            semantic.ErrorAccessDenied,
					AuthoredMessage: "must not cross the neutral Runtime boundary",
				},
			)
			if code != crmCodeInsufficientPermission || message != test.want {
				t.Fatalf("code=%q message=%q, want code=%q message=%q", code, message, crmCodeInsufficientPermission, test.want)
			}
		})
	}

	code, message := crmMutationErrorProjection(
		"v63.0", "", semantic.OperationKind("unknown"),
		semantic.OperationError{Kind: semantic.ErrorAccessDenied, AuthoredMessage: "internal detail"},
	)
	if code != crmCodeInsufficientPermission || message != "Insufficient access" {
		t.Fatalf("unaddressable denial code=%q message=%q", code, message)
	}
}

func TestSingleCreateObjectAccessDenialMatchesStagingWireContract(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{{
				Index: 0, Kind: semantic.OperationCreate,
				Errors: []semantic.OperationError{{Kind: semantic.ErrorAccessDenied}},
			}},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Credits_Topup__c", `{}`))
	const want = `[{"errorCode":"FORBIDDEN","message":"permission denied: cannot Create Credits_Topup__c"}]` + "\n"
	if recorder.Code != http.StatusForbidden || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s, want status=%d body=%s", recorder.Code, recorder.Body.String(), http.StatusForbidden, want)
	}
}

func TestServiceProjectsInvalidFieldWithRequestObjectContext(t *testing.T) {
	for _, test := range []struct {
		name       string
		path       string
		body       string
		wantStatus int
		wantBody   string
	}{
		{
			name:       "single",
			path:       "/services/data/v63.0/sobjects/Account",
			body:       `{"UnknownField":"value"}`,
			wantStatus: http.StatusBadRequest,
			wantBody:   `[{"errorCode":"INVALID_FIELD","message":"field 'UnknownField' does not exist on object 'Account'","fields":["UnknownField"]}]` + "\n",
		},
		{
			name:       "composite uses the failing position",
			path:       "/services/data/v63.0/composite/sobjects",
			body:       `{"records":[{"attributes":{"type":"Account"},"Name":"Ada"},{"attributes":{"type":"Contact"},"UnknownField":"value"}]}`,
			wantStatus: http.StatusOK,
			wantBody:   `[{"created":true,"errors":[],"id":"created-1","success":true},{"errors":[{"fields":["UnknownField"],"message":"field 'UnknownField' does not exist on object 'Contact'","statusCode":"INVALID_FIELD"}],"id":"","success":false}]` + "\n",
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				response := successfulMutationResponse(t, request)
				index := len(response.Results) - 1
				response.Results[index] = semantic.OperationResult{
					Index: uint32(index), Kind: request.Operations[index].Kind,
					Errors: []semantic.OperationError{{Kind: semantic.ErrorInvalidField, Fields: []string{"UnknownField"}}},
				}
				return response, nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, test.path, test.body))
			if recorder.Code != test.wantStatus || recorder.Body.String() != test.wantBody {
				t.Fatalf("status=%d body=%s, want status=%d body=%s", recorder.Code, recorder.Body.String(), test.wantStatus, test.wantBody)
			}
		})
	}
}

func TestServiceProjectsDurableObjectNotFoundPreflightToExistingCRMError(t *testing.T) {
	for _, test := range []struct {
		name   string
		method string
		path   string
		body   string
	}{
		{name: "single", method: http.MethodPost, path: "/services/data/v63.0/sobjects/UnknownItem", body: `{}`},
		{name: "collection", method: http.MethodPost, path: "/services/data/v63.0/composite/sobjects", body: `{"records":[{"attributes":{"type":"KnownItem"}},{"attributes":{"type":"UnknownItem"}}]}`},
	} {
		t.Run(test.name, func(t *testing.T) {
			var calls atomic.Uint64
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				calls.Add(1)
				digest, err := semantic.CommandDigest(request)
				if err != nil {
					t.Fatal(err)
				}
				results := make([]semantic.OperationResult, len(request.Operations))
				for index, operation := range request.Operations {
					kind := semantic.ErrorProcessingHalted
					if index == len(request.Operations)-1 {
						kind = semantic.ErrorObjectNotFound
					}
					results[index] = semantic.OperationResult{Index: uint32(index), Kind: operation.Kind, RecordID: operation.RecordID,
						Errors: []semantic.OperationError{{Kind: kind, Fields: []string{}}}}
				}
				return semantic.Response{CommandID: request.CommandID, CommandDigest: digest, Results: results,
					Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z"}, nil
			})
			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(test.method, test.path, test.body))
			want := `[{"errorCode":"NOT_FOUND","message":"Object not found"}]` + "\n"
			if recorder.Code != http.StatusNotFound || recorder.Body.String() != want || calls.Load() != 1 {
				t.Fatalf("status=%d calls=%d body=%s", recorder.Code, calls.Load(), recorder.Body.String())
			}
		})
	}
}

func TestServiceProjectsCreateFromSourceGuardWithRequestedAPIVersion(t *testing.T) {
	for _, apiVersion := range []string{"v59.0", "v63.0"} {
		t.Run(apiVersion, func(t *testing.T) {
			service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
				digest, err := semantic.CommandDigest(request)
				if err != nil {
					t.Fatal(err)
				}
				return semantic.Response{
					CommandID: request.CommandID, CommandDigest: digest, Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
					Results: []semantic.OperationResult{{
						Index: 0, Kind: semantic.OperationCreate, Success: false,
						Errors: []semantic.OperationError{{
							Kind: semantic.ErrorInvalidOperation, Fields: []string{},
							CreateFromSourceGuard: &semantic.CreateFromSourceGuard{ObjectID: "TargetObject", ActionIDs: []string{"createTarget"}},
						}},
					}},
				}, nil
			})

			recorder := httptest.NewRecorder()
			service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/"+apiVersion+"/sobjects/TargetObject", `{}`))
			var response []map[string]any
			if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil || recorder.Code != http.StatusBadRequest || len(response) != 1 {
				t.Fatalf("status=%d response=%#v err=%v body=%s", recorder.Code, response, err, recorder.Body.String())
			}
			want := "Direct create of TargetObject with a configured source-FK populated is not permitted. " +
				"Invoke the owning standard action endpoint instead: /services/data/" + apiVersion + "/actions/standard/createTarget"
			if response[0]["errorCode"] != crmCodeInvalidOperation || response[0]["message"] != want {
				t.Fatalf("response=%#v, want message %q", response, want)
			}
		})
	}
}

func TestMutationFieldProjectionIsDeterministic(t *testing.T) {
	first, err := mutationFields(map[string]any{"b": json.Number("0"), "a": false}, false)
	if err != nil {
		t.Fatal(err)
	}
	second, err := mutationFields(map[string]any{"a": false, "b": json.Number("0")}, false)
	if err != nil || !reflect.DeepEqual(first, second) {
		t.Fatalf("first=%#v second=%#v err=%v", first, second, err)
	}
}

func TestMutationFieldProjectionExcludesRecordCarrierMetadata(t *testing.T) {
	fields, err := mutationFields(map[string]any{
		"Name":            "Ada",
		"Id":              "001-test",
		"attributes":      map[string]any{"type": "Account"},
		"ATTRIBUTES":      map[string]any{"type": "Account"},
		"attributes.type": "Account",
		"_objectType":     "Account",
		"_exactDecimals":  map[string]any{"Amount": "12.50"},
		"_metadata":       map[string]any{"source": "record-carrier"},
	}, true)
	if err != nil {
		t.Fatal(err)
	}
	if len(fields) != 1 || fields[0].Name != "Name" {
		t.Fatalf("projected fields = %#v, want only Name", fields)
	}
}

func TestCompositeMutationPreservesFieldlessValidationErrorGrammar(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest,
			Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{{
				Index: 0, Kind: semantic.OperationCreate,
				Errors: []semantic.OperationError{{Kind: semantic.ErrorCustomValidation, Fields: []string{}}},
			}},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/composite/sobjects", `{"records":[{"attributes":{"type":"Account"},"Name":"Ada"}]}`))
	if recorder.Code != http.StatusOK {
		t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
	}
	const want = `[{"errors":[{"fields":[],"message":"","statusCode":"FIELD_CUSTOM_VALIDATION_EXCEPTION"}],"id":"","success":false}]` + "\n"
	if recorder.Body.String() != want {
		t.Fatalf("body=%s, want %s", recorder.Body.String(), want)
	}
}

func TestSingleMutationProjectsAllValidationFailuresWithFields(t *testing.T) {
	service, _ := newMutationService(t, func(_ context.Context, _ string, request semantic.Request) (semantic.Response, error) {
		digest, err := semantic.CommandDigest(request)
		if err != nil {
			t.Fatal(err)
		}
		return semantic.Response{
			CommandID: request.CommandID, CommandDigest: digest,
			Receipts: mutationReceipts(), OutcomeExpiresAtUTC: "2026-07-20T12:30:00Z",
			Results: []semantic.OperationResult{{
				Index: 0, Kind: semantic.OperationCreate,
				Errors: []semantic.OperationError{
					{Kind: semantic.ErrorCustomValidation, AuthoredMessage: "Existing Database is required", Fields: []string{"Existing_Database__c"}},
					{Kind: semantic.ErrorCustomValidation, AuthoredMessage: "IQM Completed Date is required", Fields: []string{"IQM_Completed_Date__c"}},
				},
			}},
		}, nil
	})
	recorder := httptest.NewRecorder()
	service.ServeHTTP(recorder, mutationHTTPRequest(http.MethodPost, "/services/data/v63.0/sobjects/Lead", `{"IQM_Completed__c":true}`))

	const want = `[{"errorCode":"FIELD_CUSTOM_VALIDATION_EXCEPTION","message":"Existing Database is required","fields":["Existing_Database__c"]},{"errorCode":"FIELD_CUSTOM_VALIDATION_EXCEPTION","message":"IQM Completed Date is required","fields":["IQM_Completed_Date__c"]}]` + "\n"
	if recorder.Code != http.StatusBadRequest || recorder.Body.String() != want {
		t.Fatalf("status=%d body=%s, want status=%d body=%s", recorder.Code, recorder.Body.String(), http.StatusBadRequest, want)
	}
}
