package reconcile

import "strings"

// The normalization layer keeps Proxmox round-trip quirks from reading as drift.
// Reconcile compares NORMALIZED desired-vs-actual so a value the agent wrote and then
// read back equal does not look like a change. `description`'s trailing newline (the
// first proven case, slice-4 pre-check) is the seed; the structure is a per-field
// registry so other quirks (omitted-default fields, boolean coercions, list ordering)
// slot in as they are discovered — each is a Normalizer mapped to a field name.

// Normalizer maps a raw field value to its canonical comparison form. It must be
// idempotent: Normalizer(Normalizer(x)) == Normalizer(x).
type Normalizer func(string) string

// FieldNormalizers maps a Proxmox config field name to its Normalizer. A field with
// no entry compares verbatim (identity).
type FieldNormalizers map[string]Normalizer

// DefaultNormalizers is the production set. Today only `description` needs one (PVE
// appends a trailing newline on read). New quirks are added here as they are found.
func DefaultNormalizers() FieldNormalizers {
	return FieldNormalizers{
		"description": NormDescription,
	}
}

// Norm returns the canonical comparison form of value for field, applying the
// field's Normalizer if one is registered, else the value unchanged.
func (n FieldNormalizers) Norm(field, value string) string {
	if f, ok := n[field]; ok && f != nil {
		return f(value)
	}
	return value
}

// Equal reports whether two raw values for field are equal AFTER normalization.
func (n FieldNormalizers) Equal(field, a, b string) bool {
	return n.Norm(field, a) == n.Norm(field, b)
}

// NormDescription strips the trailing newline(s) PVE appends to the LXC `description`
// field on read, so a written value round-trips equal. (Proven slice-4 pre-check:
// PVE stores `description` with a trailing "\n"; a verbatim compare always mismatches.)
// Exported so the --selftest=task description round-trip uses the SAME helper the
// reconciler does — one source of truth for the quirk.
func NormDescription(s string) string { return strings.TrimRight(s, "\n") }
