package processor
import (
	"bytes"
	"cook/utils"
	"io"
	"os"
	"regexp"
	"strings"
	"testing"
	"github.com/stretchr/testify/assert"
)
// TestLogger implements the Logger interface for testing
type TestLogger struct {
	T *testing.T // Reference to the test's *testing.T
}
func (l *TestLogger) Printf(format string, v ...any) {
	if l.T != nil {
		l.T.Logf(format, v...)
	}
}
// Helper function to normalize whitespace for comparison
func normalizeWhitespace(s string) string {
	// Replace all whitespace with a single space
	re := regexp.MustCompile(`\s+`)
	return re.ReplaceAllString(strings.TrimSpace(s), " ")
}
func ApiAdaptor(content string, regex string, lua string) (string, int, int, error) {
	command := utils.ModifyCommand{
		Regex:    regex,
		Lua:      lua,
		LogLevel: "TRACE",
	}
	commands, err := ProcessRegex(content, command, "test")
	if err != nil {
		return "", 0, 0, err
	}
	result, modifications := utils.ExecuteModifications(commands, content)
	return result, modifications, len(commands), nil
}
func TestBuildLuaScript(t *testing.T) {
	cases := []struct {
		input    string
		expected string
	}{
		{"s1 .. '_suffix'", "v1 = s1 .. '_suffix'"},
		{"v1 * 1.5", "v1 = v1 * 1.5"},
		{"v1 + 10", "v1 = v1 + 10"},
		{"v1 * 2", "v1 = v1 * 2"},
		{"v1 * v2", "v1 = v1 * v2"},
		{"v1 / v2", "v1 = v1 / v2"},
		{"12", "v1 = 12"},
	}
	for _, c := range cases {
		result := PrependLuaAssignment(c.input)
		assert.Equal(t, c.expected, result, "BuildLuaScript(%q): expected %q, got %q", c.input, c.expected, result)
	}
}
func TestSimpleValueMultiplication(t *testing.T) {
	content := `
    - 
        100
    `
	expected := `
- 
        150
    `
	result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1 = v1*1.5")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestShorthandNotation(t *testing.T) {
	content := `
- 
        100
    `
	expected := `
- 
        150
    `
	result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1*1.5")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestShorthandNotationFloats(t *testing.T) {
	content := `
- 
        10.5
    `
	expected := `
- 
        15.75
    `
	result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+\.\d+)`, "v1*1.5")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestArrayNotation(t *testing.T) {
	content := `
    
        10
        20
        30
    
`
	expected := `
    
        20
        40
        60
    
`
	result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1*2")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches)
	assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMultipleNumericMatches(t *testing.T) {
	content := `
    50
    100
    200
`
	expected := `
    100
    200
    400
`
	result, mods, matches, err := ApiAdaptor(content, `(\d+)`, "v1*2")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches)
	assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMultipleStringMatches(t *testing.T) {
	content := `
    John
    Mary
`
	expected := `
    John_modified
    Mary_modified
`
	result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = s1 .. "_modified"`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestStringUpperCase(t *testing.T) {
	content := `
    John
    Mary
`
	expected := `
    JOHN
    MARY
`
	result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = string.upper(s1)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestStringConcatenation(t *testing.T) {
	content := `
    Apple
    Banana
`
	expected := `
    Apple_fruit
    Banana_fruit
`
	result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = s1 .. "_fruit"`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
// Added from main_test.go
func TestDecimalValues(t *testing.T) {
	content := `
- 
				10.5
				2.5
			`
	expected := `
- 
				26.25
				2.5
			`
	regex := regexp.MustCompile(`(?s)([0-9.]+).*?([0-9.]+)`)
	luaExpr := BuildLuaScript("v1 = v1 * v2")
	result, _, _, err := ApiAdaptor(content, regex.String(), luaExpr)
	assert.NoError(t, err, "Error processing content: %v", err)
	normalizedModified := normalizeWhitespace(result)
	normalizedExpected := normalizeWhitespace(expected)
	assert.Equal(t, normalizedExpected, normalizedModified, "Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified)
}
// Added from main_test.go
func TestLuaMathFunctions(t *testing.T) {
	content := `
- 
				16
			`
	expected := `
- 
				4
			`
	regex := regexp.MustCompile(`(?s)(\d+)`)
	luaExpr := BuildLuaScript("v1 = math.sqrt(v1)")
	modifiedContent, _, _, err := ApiAdaptor(content, regex.String(), luaExpr)
	assert.NoError(t, err, "Error processing content: %v", err)
	normalizedModified := normalizeWhitespace(modifiedContent)
	normalizedExpected := normalizeWhitespace(expected)
	assert.Equal(t, normalizedExpected, normalizedModified, "Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified)
}
// Added from main_test.go
func TestDirectAssignment(t *testing.T) {
	content := `
- 
				100
			`
	expected := `
- 
				0
			`
	regex := regexp.MustCompile(`(?s)(\d+)`)
	luaExpr := BuildLuaScript("=0")
	modifiedContent, _, _, err := ApiAdaptor(content, regex.String(), luaExpr)
	assert.NoError(t, err, "Error processing content: %v", err)
	normalizedModified := normalizeWhitespace(modifiedContent)
	normalizedExpected := normalizeWhitespace(expected)
	assert.Equal(t, normalizedExpected, normalizedModified, "Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified)
}
// Added from main_test.go
func TestStringAndNumericOperations(t *testing.T) {
	tests := []struct {
		name           string
		input          string
		regexPattern   string
		luaExpression  string
		expectedOutput string
		expectedMods   int
	}{
		{
			name:           "Basic numeric multiplication",
			input:          "42",
			regexPattern:   "(\\d+)",
			luaExpression:  "v1 = v1 * 2",
			expectedOutput: "84",
			expectedMods:   1,
		},
		{
			name:           "Basic string manipulation",
			input:          "test",
			regexPattern:   "(.*?)",
			luaExpression:  "s1 = string.upper(s1)",
			expectedOutput: "TEST",
			expectedMods:   1,
		},
		{
			name:           "String concatenation",
			input:          "abc123",
			regexPattern:   "(.*?)",
			luaExpression:  "s1 = s1 .. '_modified'",
			expectedOutput: "abc123_modified",
			expectedMods:   1,
		},
		{
			name:           "Numeric value from string using num()",
			input:          "19.99",
			regexPattern:   "(.*?)",
			luaExpression:  "v1 = num(s1) * 1.2",
			expectedOutput: "23.987999999999996",
			expectedMods:   1,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Compile the regex pattern with multiline support
			pattern := "(?s)" + tt.regexPattern
			luaExpr := BuildLuaScript(tt.luaExpression)
			// Process with our function
			result, modCount, _, err := ApiAdaptor(tt.input, pattern, luaExpr)
			assert.NoError(t, err, "Process function failed: %v", err)
			// Check results
			assert.Equal(t, tt.expectedOutput, result, "Expected output: %s, got: %s", tt.expectedOutput, result)
			assert.Equal(t, tt.expectedMods, modCount, "Expected %d modifications, got %d", tt.expectedMods, modCount)
		})
	}
}
// Added from main_test.go
func TestEdgeCases(t *testing.T) {
	tests := []struct {
		name           string
		input          string
		regexPattern   string
		luaExpression  string
		expectedOutput string
		expectedMods   int
	}{
		{
			name:           "Empty capture group",
			input:          "",
			regexPattern:   "(.*?)",
			luaExpression:  "s1 = 'filled'",
			expectedOutput: "filled",
			expectedMods:   1,
		},
		{
			name:           "Non-numeric string with numeric operation",
			input:          "abc",
			regexPattern:   "(.*?)",
			luaExpression:  "v1 = v1 * 2",        // This would fail if we didn't handle strings properly
			expectedOutput: "abc", // Should remain unchanged
			expectedMods:   0,                    // No modifications
		},
		{
			name:           "Invalid number conversion",
			input:          "abc",
			regexPattern:   "(.*?)",
			luaExpression:  "v1 = num(s1) + 10", // num(s1) should return 0
			expectedOutput: "10",
			expectedMods:   1,
		},
		{
			name:           "Multiline string",
			input:          "Line 1\nLine 2",
			regexPattern:   "(.*?)",
			luaExpression:  "s1 = string.gsub(s1, '\\n', ' - ')",
			expectedOutput: "Line 1 - Line 2",
			expectedMods:   1,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Make sure the regex can match across multiple lines
			pattern := "(?s)" + tt.regexPattern
			luaExpr := BuildLuaScript(tt.luaExpression)
			// Process with our function
			result, modCount, _, err := ApiAdaptor(tt.input, pattern, luaExpr)
			assert.NoError(t, err, "Process function failed: %v", err)
			// Check results
			assert.Equal(t, tt.expectedOutput, result, "Expected output: %s, got: %s", tt.expectedOutput, result)
			assert.Equal(t, tt.expectedMods, modCount, "Expected %d modifications, got %d", tt.expectedMods, modCount)
		})
	}
}
func TestNamedCaptureGroups(t *testing.T) {
	content := `
- 
        100
    `
	expected := `
- 
        200
    `
	result, mods, matches, err := ApiAdaptor(content, `(?s)(?\d+)`, "amount = amount * 2")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureGroupsNum(t *testing.T) {
	content := `
- 
        100
    `
	expected := `
- 
        200
    `
	result, mods, matches, err := ApiAdaptor(content, `(?s)(?!num)`, "amount = amount * 2")
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMultipleNamedCaptureGroups(t *testing.T) {
	content := `
    Widget
    15.99
    10
`
	expected := `
    WIDGET
    23.99
    15
`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s)(?[^<]+).*?(?\d+\.\d+).*?(?\d+)`,
		`prodName = string.upper(prodName)
		 prodPrice = round(prodPrice + 8, 2)
		 prodQty = prodQty + 5`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches)
	assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMixedIndexedAndNamedCaptures(t *testing.T) {
	content := `
    12345
    value
`
	expected := `
    24690
    VALUE
`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s)(\d+).*?(?[^<]+)`,
		`v1 = v1 * 2
		 dataField = string.upper(dataField)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestComplexNestedNamedCaptures(t *testing.T) {
	content := `
			John Smith
			32
		 
		
			john@example.com
		
	`
	expected := `
		
			JOHN SMITH (32)
			32
		 
		
			john@example.com
		
	`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s).*?(?[^<]+).*?(?\d+)`,
		`fullName = string.upper(fullName) .. " (" .. age .. ")"`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureWithVariableReadback(t *testing.T) {
	content := `
    100
    200
`
	expected := `
    150
    300
`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s)(?\d+).*?(?\d+)`,
		`hp = hp * 1.5
		 mp = mp * 1.5`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureWithSpecialCharsInName(t *testing.T) {
	content := ``
	expected := ``
	result, mods, matches, err := ApiAdaptor(content,
		``
	expected := ``
	result, mods, matches, err := ApiAdaptor(content,
		`attr="(?.*?)"`,
		`value = value == "" and "default" or value`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMultipleNamedCapturesInSameLine(t *testing.T) {
	content := ``
	expected := ``
	result, mods, matches, err := ApiAdaptor(content,
		`x="(?\d+)" y="(?\d+)" width="(?\d+)" height="(?\d+)"`,
		`x = x * 2
		 y = y * 2
		 w = w * 2
		 h = h * 2`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 4, matches, "Expected 4 matches, got %d", matches)
	assert.Equal(t, 4, mods, "Expected 4 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestConditionalNamedCapture(t *testing.T) {
	content := `
	
`
	expected := `
`
	result, mods, matches, err := ApiAdaptor(content,
		`
`
	expected := `
	
	
	`
	result, mods, matches, err := ApiAdaptor(content,
		`
	`
	expected := `
`
	result, mods, matches, err := ApiAdaptor(content,
		`
',
			price, qty, price * qty)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	result = normalizeWhitespace(result)
	expected = normalizeWhitespace(expected)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureWithGlobals(t *testing.T) {
	content := `25`
	expected := `77`
	result, mods, matches, err := ApiAdaptor(content,
		`(?\d+)`,
		`if unit == "C" then
		  value = value * 9/5 + 32
		  unit = "F"
		elseif unit == "F" then
		  value = (value - 32) * 5/9
		  unit = "C"
		end`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestMixedDynamicAndNamedCaptures(t *testing.T) {
	content := `
	
	
	`
	expected := `
	
	
	`
	result, mods, matches, err := ApiAdaptor(content,
		``,
		`-- Uppercase the name
		 colorName = string.upper(colorName)
		 -- Create hex color
		 local hex = string.format("#%02X%02X%02X", tonumber(r), tonumber(g), tonumber(b))
		 -- Replace the entire match
		 replacement = string.format('',
		                            r, g, b, colorName, hex)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	result = normalizeWhitespace(result)
	expected = normalizeWhitespace(expected)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCapturesWithMultipleReferences(t *testing.T) {
	content := `Hello world`
	expected := `HELLO WORLD`
	result, mods, matches, err := ApiAdaptor(content,
		`(?[^<]+)`,
		`local uppercaseContent = string.upper(content)
		 local contentLength = string.len(content)
		 replacement = string.format('%s',
		                            contentLength, uppercaseContent)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureWithJsonData(t *testing.T) {
	content := `{"name":"John","age":30}`
	expected := `{"name":"JOHN","age":30}`
	result, mods, matches, err := ApiAdaptor(content,
		`(?\{.*?\})`,
		`-- Parse JSON (simplified, assumes valid JSON)
		 local name = json:match('"name":"([^"]+)"')
		 local upperName = string.upper(name)
		 json = json:gsub('"name":"([^"]+)"', '"name":"' .. upperName .. '"')`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestNamedCaptureInXML(t *testing.T) {
	content := `
	
		ABC-123
		19.99
		25
	
	`
	expected := `
	
		ABC-123
		23.99
		20
	
	`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s)(?\d+\.\d+).*?(?\d+)`,
		`-- Add 20% to price if USD
		 if currency == "USD" then
		   price = round(price * 1.20, 2)
		 end
		 -- Reduce stock by 5
		 stock = stock - 5`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches)
	assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
func TestComprehensiveNamedCaptures(t *testing.T) {
	content := `
	
		
			Widget A
			19.99
			15
		
		
			Widget B
			29.99
			0
		
		
			Widget C
			39.99
			5
		
	
	`
	expected := `
	
		
			WIDGET A
			15.99
			15
		
		
			Widget B
			29.99
			0
		
		
			WIDGET C
			39.99
			5
		
	
	`
	result, mods, matches, err := ApiAdaptor(content,
		`(?s)]*>\s*(?[^<]+)\s*(?\d+\.\d+)\s*(?\d+)`,
		`-- Only process in-stock items
		if status == "in-stock" then
			-- Transform name to uppercase
			product_name = string.upper(product_name)
			-- Apply discount based on currency
			local discounted = true
			if currency == "USD" then
				price = round(price * 0.8, 2)  -- 20% discount for USD
			elseif currency == "GBP" then
				price = round(price * 0.8, 2)  -- 20% discount for GBP
				price = price + 8  -- Add shipping cost for GBP
			else
				discounted = false
			end
			-- Add discounted attribute
			replacement = string.format('\n\t\t\t%s\n\t\t\t%.2f\n\t\t\t%s',
				sku, status, tostring(discounted), product_name, currency, price, qty)
		else
			-- Add discounted attribute for out-of-stock items (always false)
			replacement = string.format('\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s',
				sku, status, product_name, currency, price, qty)
		end`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches)
	assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods)
	// Normalize whitespace for comparison
	normalizedResult := normalizeWhitespace(result)
	normalizedExpected := normalizeWhitespace(expected)
	assert.Equal(t, normalizedExpected, normalizedResult, "Expected content to be different")
}
func TestVariousNamedCaptureFormats(t *testing.T) {
	content := `
	
		
		
		
	
	`
	expected := `
	
		
		
		
	
	`
	result, mods, matches, err := ApiAdaptor(content,
		``,
		`-- Prefix the ID with "ID-"
		id_num = "ID-" .. id_num
		print(id_num)
		print(val)
		print(status)
		-- Double the value except for inactive status
		if not status or status ~= "inactive" then
			val = val * 2
		end
		-- Convert status to uppercase if present and active
		if status and status == "active" then
			status = string.upper(status)
		end
		-- Build the replacement based on whether status exists
		if status then
			replacement = string.format('', id_num, val, status)
		else
			replacement = string.format('', id_num, val)
		end`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches)
	assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods)
	normalizedResult := normalizeWhitespace(result)
	normalizedExpected := normalizeWhitespace(expected)
	assert.Equal(t, normalizedExpected, normalizedResult, "Expected content to be different")
}
func TestSimpleNamedCapture(t *testing.T) {
	content := ``
	expected := ``
	result, mods, matches, err := ApiAdaptor(content,
		`name="(?[^"]+)"`,
		`product_name = string.upper(product_name)`)
	assert.NoError(t, err, "Error processing content: %v", err)
	assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches)
	assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods)
	assert.Equal(t, expected, result, "Expected content to be different")
}
// Pattern without "(?s)" prefix gets modified to include it
func TestPatternWithoutPrefixGetsModified(t *testing.T) {
	// Setup
	pattern := "some.*pattern"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)some.*pattern"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Empty string input returns "(?s)"
func TestEmptyStringReturnsWithPrefix(t *testing.T) {
	// Setup
	pattern := ""
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Named group with "!num" pattern gets replaced with proper regex for numbers
func TestNamedGroupNumPatternReplacement(t *testing.T) {
	// Setup
	pattern := "(?!num)"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)(?-?\\d*\\.?\\d+)"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// "!any" placeholder gets replaced with ".*?" pattern
func TestAnyPlaceholderReplacement(t *testing.T) {
	// Setup
	pattern := "start!anyend"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)start.*?end"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// "!rep(pattern, count)" correctly repeats the pattern with separators
func TestRepPatternRepetition(t *testing.T) {
	// Setup
	pattern := "!rep(a, 3)"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)a.*?a.*?a"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Multiple different placeholders in the same pattern are all correctly replaced
func TestMultiplePlaceholdersReplacedCorrectly(t *testing.T) {
	// Setup
	pattern := "(?s)some(?!num)text!anymore!rep(!num, 3)"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)some(?-?\\d*\\.?\\d+)text.*?more(-?\\d*\\.?\\d+).*?(-?\\d*\\.?\\d+).*?(-?\\d*\\.?\\d+)"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Pattern already containing "(?s)" prefix remains unchanged
func TestPatternWithPrefixRemainsUnchanged(t *testing.T) {
	// Setup
	pattern := "(?s)some.*pattern"
	// Redirect stdout to capture fmt.Printf output
	oldStdout := os.Stdout
	r, w, _ := os.Pipe()
	os.Stdout = w
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Restore stdout
	w.Close()
	os.Stdout = oldStdout
	// Read captured output
	var buf bytes.Buffer
	io.Copy(&buf, r)
	output := buf.String()
	// Verify results
	expectedPattern := "(?s)some.*pattern"
	assert.Equal(t, expectedPattern, result, "Expected pattern to remain %q, got %q", expectedPattern, result)
	expectedOutput := ""
	assert.Equal(t, expectedOutput, output, "Expected no output message, got %q", output)
}
// Malformed "!rep" pattern without proper parameters returns unchanged match
func TestMalformedRepPatternReturnsUnchanged(t *testing.T) {
	// Setup
	pattern := "!rep(somepattern)" // Malformed !rep pattern without count
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := "(?s)!rep(somepattern)"
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Nested placeholder patterns (e.g., "!rep(!num, 3)")
func TestNestedPlaceholderPatterns(t *testing.T) {
	// Setup
	pattern := "!rep(!num, 3)"
	// Execute function
	result := resolveRegexPlaceholders(pattern)
	// Verify results
	expectedPattern := `(?s)(-?\d*\.?\d+).*?(-?\d*\.?\d+).*?(-?\d*\.?\d+)`
	assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result)
}
// Returns empty slice when input is empty
func TestDeduplicateGroupsWithEmptyInput(t *testing.T) {
	// Arrange
	var captureGroups []*CaptureGroup
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Empty(t, result, "Expected empty slice when input is empty")
}
// Input with all overlapping groups returns empty slice
func TestDeduplicateGroupsWithAllOverlappingGroups(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{
			Name:  "group1",
			Range: [2]int{10, 20},
		},
		{
			Name:  "group2",
			Range: [2]int{15, 25},
		},
		{
			Name:  "group3",
			Range: [2]int{5, 15},
		},
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Len(t, result, 1, "Expected only one group to remain after deduplication")
	assert.Equal(t, "group1", result[0].Name, "Expected first group to be kept")
}
// Successfully adds non-overlapping capture groups to result
func TestDeduplicateGroupsWithNonOverlappingInput(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{Name: "Group1", Range: [2]int{0, 5}},
		{Name: "Group2", Range: [2]int{6, 10}},
		{Name: "Group3", Range: [2]int{11, 15}},
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Equal(t, 3, len(result), "Expected all non-overlapping groups to be added")
	assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be in the result")
	assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be in the result")
	assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be in the result")
}
// Correctly identifies and filters out overlapping capture groups
func TestDeduplicateGroupsWithOverlappingInput(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{Name: "group1", Range: [2]int{0, 5}},
		{Name: "group2", Range: [2]int{3, 8}}, // Overlaps with group1
		{Name: "group3", Range: [2]int{10, 15}},
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Len(t, result, 2, "Expected two non-overlapping capture groups")
	assert.Equal(t, "group1", result[0].Name, "Expected group1 to be in the result")
	assert.Equal(t, "group3", result[1].Name, "Expected group3 to be in the result")
}
// Handles multiple non-overlapping groups correctly
func TestDeduplicateGroupsWithNonOverlappingGroups(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{Name: "Group1", Range: [2]int{0, 5}},
		{Name: "Group2", Range: [2]int{6, 10}},
		{Name: "Group3", Range: [2]int{11, 15}},
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Equal(t, 3, len(result), "Expected all groups to be included as they do not overlap")
	assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be the first in the result")
	assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be the second in the result")
	assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be the third in the result")
}
// Groups with identical ranges are considered overlapping
func TestDeduplicateGroupsWithIdenticalRanges(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{Name: "Group1", Range: [2]int{0, 5}},
		{Name: "Group2", Range: [2]int{0, 5}}, // Identical range to Group1
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Len(t, result, 1, "Expected only one group in the result due to identical ranges")
	assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be in the result")
}
// Groups with adjacent but non-overlapping ranges (end of one = start of another)
func TestDeduplicateGroupsWithAdjacentNonOverlappingRanges(t *testing.T) {
	// Arrange
	captureGroups := []*CaptureGroup{
		{Name: "Group1", Range: [2]int{0, 5}},
		{Name: "Group2", Range: [2]int{5, 10}},
		{Name: "Group3", Range: [2]int{10, 15}},
	}
	// Act
	result := deduplicateGroups(captureGroups)
	// Assert
	assert.Equal(t, 3, len(result), "Expected all groups to be included as they are adjacent but non-overlapping")
	assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be the first in the result")
	assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be the second in the result")
	assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be the third in the result")
}