package boundary_test

import (
	"path/filepath"
	"strings"
	"testing"
)

// L0-C / C6 anti-regrowth seal.
//
// PR-C1 (#3318) deleted the dead SF-skinned metadata REST handlers
// (metadata_{schema,field,handler,validation}_handler.go) from the app-blind L0
// surface. Those handlers emitted the Salesforce Describe/Tooling wire envelope:
// the Describe-global {"sobjects":[...]} payload key and the Tooling API
// ":id" routing convention.
//
// The SF Describe/Tooling wire envelope is L1-owned (dialect-sf-crm, which holds
// describe_dtos.go / metadata_authoring.go / tooling_query.go). The neutral
// contract seam (contract.Metadata.Describe -> *models.ObjectMetadata,
// "without dialect URLs or transport envelopes") is what app-blind L0 speaks.
// App-blind L0 must NOT mint the SF wire envelope, so the count below must stay
// at ZERO.
//
// Markers are deliberately wire-only and precise:
//   - "sobjects" (quoted): the SF Describe-global {"sobjects":[...]} envelope key.
//     The bare token sobjects is NOT used because it false-positives on neutral
//     engine names (ScanRowsToSObjects, querySObjectString,
//     neutralRecordsFromSObjects).
//   - "// Tooling API uses :id": the Tooling-API routing comment the dead
//     handlers carried.
//
// Deliberately NOT sealed: displayNameField / object_api_name / calculatedFormula.
// Those are legitimate engine validation/storage concepts, not wire skin.
//
// backend/distributions (L1) is intentionally NOT scanned — that is where the SF
// Describe/Tooling wire envelope legitimately lives. backend/docs (generated
// swagger) and *_test.go files are also excluded. boundarygate does not scan
// backend/, so without this seal the SF Describe/Tooling wire envelope could
// silently regrow in the app-blind L0 surface. This is a count seal pinned at 0,
// not a ledger: any reintroduction is a regression, not a trackable expansion.
var l0DescribeWireSkinForbiddenMarkers = []string{
	`"sobjects"`,
	"// Tooling API uses :id",
}

func TestAppBlindL0DoesNotEmitSFDescribeWireEnvelope(t *testing.T) {
	root := repoRoot(t)

	// App-blind L0 surface. backend/distributions (L1) is deliberately excluded:
	// that is the owner of the SF Describe/Tooling wire envelope. backend/docs
	// (generated swagger) is excluded as generated.
	l0Dirs := []string{
		"backend/internal",
		"nexuscrm-analytics",
	}

	for _, relDir := range l0Dirs {
		for _, file := range productionGoFilesRecursive(t, filepath.Join(root, relDir)) {
			rel := toRepoRelative(t, root, file)
			body := readFile(t, file)
			if isGeneratedGoFile(body) {
				continue
			}
			for _, marker := range l0DescribeWireSkinForbiddenMarkers {
				if n := strings.Count(body, marker); n != 0 {
					t.Errorf("%s emits SF Describe/Tooling wire envelope marker %q %d time(s); "+
						"the SF Describe/Tooling wire envelope is L1-owned (dialect-sf-crm), "+
						"app-blind L0 must not mint it. Speak the neutral contract seam "+
						"(contract.Metadata.Describe -> *models.ObjectMetadata) instead, and "+
						"keep the SF wire shape in the dialect distribution.", rel, marker, n)
				}
			}
		}
	}
}
