package zddc

import (
	"strings"
	"testing"

	"gopkg.in/yaml.v3"
)

// TestRecordRule_RejectsNegativeFolderDistance — a folder_fields entry
// with a negative parent-distance must fail at .zddc parse time (via
// RecordRule.UnmarshalYAML), not surface as a 500 on the first record
// write.
func TestRecordRule_RejectsNegativeFolderDistance(t *testing.T) {
	src := "folder_fields:\n  originator: -1\nfilename_format: \"{originator}-{sequence}\"\n"
	var rr RecordRule
	err := yaml.Unmarshal([]byte(src), &rr)
	if err == nil {
		t.Fatal("expected error for negative folder_fields distance, got nil")
	}
	if !strings.Contains(err.Error(), "folder_fields") || !strings.Contains(err.Error(), "originator") {
		t.Errorf("error should name folder_fields + the field: %v", err)
	}
}

// TestRecordRule_AcceptsValidFolderFields — a non-negative distance
// unmarshals and round-trips.
func TestRecordRule_AcceptsValidFolderFields(t *testing.T) {
	src := "folder_fields:\n  originator: 1\nfilename_format: \"{originator}-{sequence}\"\n"
	var rr RecordRule
	if err := yaml.Unmarshal([]byte(src), &rr); err != nil {
		t.Fatalf("valid folder_fields should unmarshal: %v", err)
	}
	if rr.FolderFields["originator"] != 1 {
		t.Errorf("folder_fields[originator]=%d want 1", rr.FolderFields["originator"])
	}
}

// TestRecordRule_NegativeDistanceInRecordsMap — the same rejection
// applies when the rule is nested in a records: map (the real cascade
// shape: map[string]RecordRule decodes each value via UnmarshalYAML).
func TestRecordRule_NegativeDistanceInRecordsMap(t *testing.T) {
	src := "\"*.yaml\":\n  folder_fields:\n    originator: -2\n"
	var rules map[string]RecordRule
	if err := yaml.Unmarshal([]byte(src), &rules); err == nil {
		t.Fatal("expected error for negative distance in records map, got nil")
	}
}

// TestFieldCode_PatternValidate — pattern field codes match values
// against the anchored regex (exercises the compiled-pattern cache).
func TestFieldCode_PatternValidate(t *testing.T) {
	src := "kind: pattern\npattern: \"[0-9]{4}\"\n"
	var fc FieldCode
	if err := yaml.Unmarshal([]byte(src), &fc); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if err := fc.Validate("0042"); err != nil {
		t.Errorf("0042 should match [0-9]{4}: %v", err)
	}
	if err := fc.Validate("42"); err == nil {
		t.Error("42 should NOT match [0-9]{4} (anchored, 4 digits)")
	}
	if err := fc.Validate("0042x"); err == nil {
		t.Error("0042x should NOT match (anchored)")
	}
}
