// Package clientip exposes the helper that resolves the originating client
// IP for an inbound HTTP request. Backend trusts the value because the
// network segment between gateway and backend is the trust boundary
// (`ARCHITECTURE.md` §15-16): gateway is responsible for sanitising and
// populating `X-Forwarded-For` before the request reaches backend.
//
// Both the public-auth handler chain (handlers_auth_helpers.go) and the
// user-surface geo-counter middleware reuse the same extraction so the two
// surfaces never disagree about the IP they record.
package clientip

import (
	"net"
	"strings"

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

// ExtractSourceIP returns the originating client IP for the request behind
// c. The leftmost entry of `X-Forwarded-For` is preferred; when the header
// is absent or empty, the connection RemoteAddr is used (with the port
// stripped). The empty string is returned when neither source yields a
// usable value, which lets callers treat the result as "no IP available"
// and skip dependent work.
func ExtractSourceIP(c *gin.Context) string {
	if c == nil || c.Request == nil {
		return ""
	}
	if xff := c.GetHeader("X-Forwarded-For"); xff != "" {
		first := xff
		if idx := strings.IndexByte(first, ','); idx >= 0 {
			first = first[:idx]
		}
		return strings.TrimSpace(first)
	}
	addr := c.Request.RemoteAddr
	if host, _, err := net.SplitHostPort(addr); err == nil {
		return host
	}
	return addr
}
