package testkit

import "encoding/json"

// OptionalString supports JSON patch semantics where a field can be:
// - absent: Set=false (no change)
// - null:   Set=true, Value=nil (explicitly clear)
// - string: Set=true, Value=&string (explicitly set)
type OptionalString struct {
	Set   bool
	Value *string
}

func (value *OptionalString) UnmarshalJSON(data []byte) error {
	value.Set = true

	if string(data) == "null" {
		value.Value = nil
		return nil
	}

	var decoded string
	if err := json.Unmarshal(data, &decoded); err != nil {
		return err
	}
	value.Value = &decoded
	return nil
}

// OptionalJSONObject supports JSON patch semantics for object fields:
// - absent: Set=false (no change)
// - null:   Set=true, Value=nil (clear to empty object)
// - object: Set=true, Value=decoded object
type OptionalJSONObject struct {
	Set   bool
	Value map[string]any
}

func (value *OptionalJSONObject) UnmarshalJSON(data []byte) error {
	value.Set = true

	if string(data) == "null" {
		value.Value = nil
		return nil
	}

	var decoded map[string]any
	if err := json.Unmarshal(data, &decoded); err != nil {
		return err
	}
	value.Value = decoded
	return nil
}
