// Package audit — content-type-aware body scrub dispatch for the request
// capture middleware. Extracted from request_capture_middleware.go to keep
// both files under the 400-line budget and to localize all §14.3 body-scrub
// coverage decisions in one place.
package audit

import "strings"

// isScrubbableContentType reports whether the content-type is covered by a
// known scrubber (json or form-urlencoded). Used by strict mode to decide
// whether to drop a capture row vs pass-through the body.
//
// Empty CT on bodyless requests (GET / HEAD / DELETE without body) is
// treated as scrubbable — there is no body to leak.
func isScrubbableContentType(contentType string) bool {
	ct := strings.ToLower(contentType)
	if ct == "" {
		return true
	}
	if strings.Contains(ct, "json") {
		return true
	}
	if strings.Contains(ct, "application/x-www-form-urlencoded") {
		return true
	}
	return false
}

// scrubBodyByContentType dispatches §14.3 body scrubbing based on
// Content-Type:
//   - `application/json` (or any CT containing "json") → ScrubJSONPayload.
//   - `application/x-www-form-urlencoded` → ScrubFormBody (same blacklist).
//   - XML / text/plain / multipart → pass-through, bounded by the upstream
//     size cap. // TODO(Phase 2B): scrub XML/multipart.
//
// On parse failure for a recognized CT (malformed JSON or form body), we
// fall through to the raw bytes rather than dropping the row — strict mode
// (§14.11) is the hammer for "never write PII-risk rows"; here we preserve
// observability.
func scrubBodyByContentType(contentType string, body []byte) string {
	if len(body) == 0 {
		return ""
	}
	ct := strings.ToLower(contentType)
	if strings.Contains(ct, "json") {
		if scrubbed, err := ScrubJSONPayload(body); err == nil {
			return string(scrubbed)
		}
		return string(body)
	}
	if strings.Contains(ct, "application/x-www-form-urlencoded") {
		if scrubbed, err := ScrubFormBody(body); err == nil {
			return string(scrubbed)
		}
		return string(body)
	}
	// TODO(Phase 2B): scrub XML/multipart — for now, pass-through within cap.
	return string(body)
}
