package middleware

import (
	"bytes"
	"encoding/json"
	"strings"

	"github.com/gin-gonic/gin"
)

// The global access logger is the single request/response capture point.
// OperationAudit consumes these values after the handler returns, avoiding a
// second body read/writer wrapper.
const (
	ctxReqBodyKey    = "kra_req_body"
	ctxRespBufferKey = "kra_resp_buffer"
)

type captureWriter struct {
	gin.ResponseWriter
	body     bytes.Buffer
	maxBytes int
}

func (w *captureWriter) Write(data []byte) (int, error) {
	limit := w.maxBytes
	if limit <= 0 {
		limit = 1024
	}
	if w.body.Len() < limit {
		remaining := limit - w.body.Len()
		if len(data) > remaining {
			_, _ = w.body.Write(data[:remaining])
		} else {
			_, _ = w.body.Write(data)
		}
	}
	return w.ResponseWriter.Write(data)
}

func redactJSON(raw []byte, contentType string, limit int) string {
	if len(raw) == 0 {
		return ""
	}
	if limit <= 0 {
		limit = 1024
	}
	text := string(raw)
	if !strings.Contains(strings.ToLower(contentType), "json") {
		if len(text) > limit {
			return "[超出记录长度]"
		}
		return text
	}
	var value any
	if json.Unmarshal(raw, &value) != nil {
		if len(text) > limit {
			return "[超出记录长度]"
		}
		return text
	}
	maskOperationBody(value)
	encoded, _ := json.Marshal(value)
	if len(encoded) > limit {
		return "[超出记录长度]"
	}
	return string(encoded)
}

func stringValue(value any) string { text, _ := value.(string); return text }

func isBootstrapPath(path string) bool {
	return strings.HasSuffix(path, "/health") || strings.Contains(path, "/init/")
}
