// Package debughttp registers opt-in, loopback-only HTTP diagnostics.
package debughttp

import (
	"net"
	"net/http"
	"net/http/pprof"
	"os"

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

const pprofEnvVar = "AGENTTEAM_ENABLE_PPROF"

// RegisterPprofRoutes registers pprof routes when AGENTTEAM_ENABLE_PPROF is set.
func RegisterPprofRoutes(router *gin.Engine) {
	if os.Getenv(pprofEnvVar) == "" {
		return
	}
	pprofGroup := router.Group("/debug/pprof", localhostOnly())
	pprofGroup.GET("", gin.WrapF(pprof.Index))
	pprofGroup.GET("/", gin.WrapF(pprof.Index))
	pprofGroup.GET("/cmdline", gin.WrapF(pprof.Cmdline))
	pprofGroup.GET("/profile", gin.WrapF(pprof.Profile))
	pprofGroup.GET("/symbol", gin.WrapF(pprof.Symbol))
	pprofGroup.POST("/symbol", gin.WrapF(pprof.Symbol))
	pprofGroup.GET("/trace", gin.WrapF(pprof.Trace))
	pprofGroup.GET("/:profile", gin.WrapF(pprof.Index))
}

func localhostOnly() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		if isLoopbackRemote(ctx.Request.RemoteAddr) {
			ctx.Next()
			return
		}
		ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "pprof is only available from localhost"})
	}
}

func isLoopbackRemote(remoteAddr string) bool {
	host, _, err := net.SplitHostPort(remoteAddr)
	if err != nil {
		host = remoteAddr
	}
	ip := net.ParseIP(host)
	return ip != nil && ip.IsLoopback()
}
