package middleware

import (
	"strings"

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

const contentSecurityPolicy = "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'"

func SecurityHeaders() gin.HandlerFunc {
	return func(c *gin.Context) {
		headers := c.Writer.Header()
		headers.Set("X-Content-Type-Options", "nosniff")
		headers.Set("X-Frame-Options", "DENY")
		headers.Set("Referrer-Policy", "strict-origin-when-cross-origin")
		headers.Set("Permissions-Policy", "camera=(), microphone=(), geolocation=()")
		headers.Set("Cross-Origin-Opener-Policy", "same-origin")
		headers.Set("X-Permitted-Cross-Domain-Policies", "none")

		if shouldAttachCSP(c.FullPath(), c.Request.URL.Path) {
			headers.Set("Content-Security-Policy", contentSecurityPolicy)
		}
		if isHTTPSRequest(c) {
			headers.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
		}

		c.Next()
	}
}

func shouldAttachCSP(routePath, requestPath string) bool {
	path := strings.TrimSpace(routePath)
	if path == "" {
		path = strings.TrimSpace(requestPath)
	}
	return !strings.HasPrefix(path, "/swagger/")
}

func isHTTPSRequest(c *gin.Context) bool {
	if c.Request.TLS != nil {
		return true
	}
	return strings.EqualFold(strings.TrimSpace(c.GetHeader("X-Forwarded-Proto")), "https")
}
