package mailstore

import (
	"context"
	"net"
	"strings"
)

// spamKeywords is a tiny, obvious-spam subject keyword list — a coarse signal only.
var spamKeywords = []string{"viagra", "casino", "lottery winner", "click here now", "wire transfer urgent", "nigerian prince"}

// SpamScore is a lightweight built-in heuristic — always runs, regardless of whether
// rspamd (rspamd.go) is also enabled; both are additive, not either/or. Higher is more
// suspicious; compare against [Mailstore] spam_reject_score.
// ponytail: naive keyword/weight heuristic, not a real Bayesian/ML scorer — upgrade or
// lean harder on rspamd if false-positive rate matters.
func SpamScore(peerIP string, headers map[string]string, dkimPass, spfPass bool) int {
	score := 0
	if !spfPass {
		score += 2
	}
	if !dkimPass {
		score++
	}
	if CheckDNSBL(peerIP) {
		score += 5
	}
	subject := strings.ToLower(headers["subject"])
	for _, kw := range spamKeywords {
		if strings.Contains(subject, kw) {
			score++
		}
	}
	return score
}

// CheckDNSBL looks up peerIP against the Spamhaus ZEN DNSBL. Per RFC 5782, a listing
// response is always an A record in 127.0.0.0/8 — checking for that range (rather than
// "any resolution succeeded") avoids false positives from a resolver that hijacks
// NXDOMAIN into a search/ad page instead of returning an error.
func CheckDNSBL(peerIP string) bool {
	ip := net.ParseIP(peerIP)
	if ip == nil || ip.To4() == nil {
		return false
	}
	octets := strings.Split(ip.To4().String(), ".")
	reversed := octets[3] + "." + octets[2] + "." + octets[1] + "." + octets[0]
	addrs, err := net.DefaultResolver.LookupHost(context.Background(), reversed+".zen.spamhaus.org")
	if err != nil {
		return false
	}
	for _, a := range addrs {
		if resolved := net.ParseIP(a); resolved != nil && resolved.To4() != nil && resolved.To4()[0] == 127 {
			return true
		}
	}
	return false
}
