// Package httptransport implements this project's HTTP transport (the
// package is named httptransport, not http, so files that need both this
// package and the stdlib net/http never collide on the "http" identifier).
package httptransport

import (
	"fmt"
	"net"
	"net/http"

	"{{ module_path }}/internal/auth"
)

// IsLocalhost reports whether remoteAddr (net/http's Request.RemoteAddr
// shape, "host:port") names a loopback address. Requests from localhost
// get relaxed auth requirements — the same localhost-vs-network binding
// distinction proven useful in the reference servers (looser auth only
// when bound to localhost, never over an exposed network interface).
func IsLocalhost(remoteAddr string) bool {
	host, _, err := net.SplitHostPort(remoteAddr)
	if err != nil {
		host = remoteAddr
	}
	ip := net.ParseIP(host)
	return ip != nil && ip.IsLoopback()
}

// ExtractAuthorizationHeader parses the Authorization header off an
// incoming HTTP request, if present.
func ExtractAuthorizationHeader(headers http.Header) (string, bool) {
	value := headers.Get("Authorization")
	return value, value != ""
}

// ExtractRequestCredentials extracts the credential value for the active
// auth method's declared location (auth.HeaderLocationFor) off an
// incoming HTTP request. The extracted value is relayed verbatim to the
// facaded API — whatever the caller sent, prefixed or not.
func ExtractRequestCredentials(headers http.Header, headerLocation, headerName string) (auth.RequestCredentials, error) {
	if headerLocation != "header" {
		return auth.RequestCredentials{}, fmt.Errorf("unsupported credential location %q", headerLocation)
	}

	value := headers.Get(headerName)
	if value == "" {
		return auth.RequestCredentials{}, fmt.Errorf("missing or empty %q header", headerName)
	}

	return auth.RequestCredentials{HeaderName: headerName, Value: value}, nil
}
