package fieldpermissions

import "strings"

// AccessCoherent is the single field-grant dependency fact used by every
// write path: edit access cannot exist without read access.
func AccessCoherent(read, edit bool) bool {
	return !edit || read
}

// SplitFieldReference splits a FieldPermissions.Field value into object and
// field components. Salesforce stores the field as Object.Field; NexusCRM also
// has historical rows with the simple field API name.
func SplitFieldReference(defaultObjectAPIName, rawField string) (string, string) {
	defaultObjectAPIName = strings.TrimSpace(defaultObjectAPIName)
	rawField = strings.TrimSpace(rawField)
	if rawField == "" {
		return defaultObjectAPIName, ""
	}
	objectAPIName, fieldAPIName, ok := strings.Cut(rawField, ".")
	if !ok {
		return defaultObjectAPIName, rawField
	}
	return strings.TrimSpace(objectAPIName), strings.TrimSpace(fieldAPIName)
}

// FieldComponent returns the logical field component for a FieldPermissions row.
func FieldComponent(defaultObjectAPIName, rawField string) string {
	_, fieldAPIName := SplitFieldReference(defaultObjectAPIName, rawField)
	return fieldAPIName
}

// QualifiedField returns the Salesforce wire form, Object.Field, using
// SobjectType as the authoritative object component.
func QualifiedField(sobjectType, rawField string) string {
	sobjectType = strings.TrimSpace(sobjectType)
	fieldAPIName := FieldComponent(sobjectType, rawField)
	if sobjectType == "" {
		return fieldAPIName
	}
	if fieldAPIName == "" {
		return sobjectType
	}
	return sobjectType + "." + fieldAPIName
}

// MatchesFieldReference reports whether rawField names requestedField for the
// provided object. Matching is case-insensitive and accepts both simple and
// qualified forms.
func MatchesFieldReference(sobjectType, rawField, requestedField string) bool {
	rowObject, rowField := SplitFieldReference(sobjectType, rawField)
	reqObject, reqField := SplitFieldReference(sobjectType, requestedField)
	return strings.EqualFold(strings.TrimSpace(rowObject), strings.TrimSpace(reqObject)) &&
		strings.EqualFold(strings.TrimSpace(rowField), strings.TrimSpace(reqField))
}
