package ipguard

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

// ClientIP resolves caller IP from request remote address.
// The service relies on trusted proxy middleware to normalize RemoteAddr.
func ClientIP(r *http.Request) net.IP {
	if r == nil {
		return nil
	}
	raw := strings.TrimSpace(r.RemoteAddr)
	if raw == "" {
		return nil
	}
	if ip := net.ParseIP(raw); ip != nil {
		return ip
	}
	host, _, err := net.SplitHostPort(raw)
	if err != nil {
		return nil
	}
	return net.ParseIP(host)
}

func parseCIDRs(raw []string) ([]*net.IPNet, error) {
	blocks := make([]*net.IPNet, 0, len(raw))
	for _, item := range raw {
		clean := strings.TrimSpace(item)
		if clean == "" {
			continue
		}
		_, block, err := net.ParseCIDR(clean)
		if err != nil {
			return nil, err
		}
		blocks = append(blocks, block)
	}
	return blocks, nil
}

// Allowed reports whether clientIP is allowed by configured CIDRs.
// Empty CIDR list means unrestricted access.
func Allowed(clientIP net.IP, cidrs []string) (bool, error) {
	blocks, err := parseCIDRs(cidrs)
	if err != nil {
		return false, err
	}
	if len(blocks) == 0 {
		return true, nil
	}
	if clientIP == nil {
		return false, nil
	}
	for _, block := range blocks {
		if block.Contains(clientIP) {
			return true, nil
		}
	}
	return false, nil
}
