package httpvalidation

import (
	"errors"
	"net/http"
	"strings"
)

var (
	// ErrInvalidContentType is returned when Content-Type header is not application/json
	ErrInvalidContentType = errors.New("Content-Type must be application/json")
	// ErrMissingContentType is returned when Content-Type header is missing
	ErrMissingContentType = errors.New("Content-Type header is required")
)

// ValidateJSONContentType validates that the request has application/json Content-Type
// CWE-436: Validates Content-Type before parsing to prevent interpretation conflicts
// Accepts both "application/json" and "application/json; charset=utf-8"
func ValidateJSONContentType(r *http.Request) error {
	contentType := r.Header.Get("Content-Type")

	// Accept empty Content-Type for backward compatibility (some clients don't set it)
	if contentType == "" {
		return nil
	}

	// Check for exact match or charset variant
	if contentType == "application/json" || strings.HasPrefix(contentType, "application/json;") {
		return nil
	}

	return ErrInvalidContentType
}

// RequireJSONContentType validates that the request has application/json Content-Type
// CWE-436: Strict validation that requires Content-Type header
// Use this for new endpoints where you want to enforce the header
func RequireJSONContentType(r *http.Request) error {
	contentType := r.Header.Get("Content-Type")

	if contentType == "" {
		return ErrInvalidContentType
	}

	// Check for exact match or charset variant
	if contentType == "application/json" || strings.HasPrefix(contentType, "application/json;") {
		return nil
	}

	return ErrInvalidContentType
}

// ValidateJSONContentTypeStrict validates that the request has application/json Content-Type
// CWE-16: Configuration - Enforces strict Content-Type validation
// This version REQUIRES the Content-Type header and returns specific error for missing header
func ValidateJSONContentTypeStrict(r *http.Request) error {
	contentType := r.Header.Get("Content-Type")

	// Require Content-Type header (no empty allowed)
	if contentType == "" {
		return ErrMissingContentType
	}

	// Check for exact match or charset variant
	if contentType == "application/json" || strings.HasPrefix(contentType, "application/json;") {
		return nil
	}

	return ErrInvalidContentType
}
