package regexp2

var (
	// DefaultUnmarshalOptions used when unmarshaling a regex from text
	DefaultUnmarshalOptions = None
	// DefaultOptimizationOptions controls the default memory/performance trade-offs used by Compile.
	DefaultOptimizationOptions = OptimizationOptions{
		MaxBacktrackingStackSize:     100000,
		MaxCachedRuneBufferLength:    256 << 10,
		MaxCachedReplaceBufferLength: 256 << 10,
		MaxCachedReplacerDataEntries: 16,
		MaxCachedReplacerDataBytes:   4 << 10,
		DisableCharClassASCIIBitmap:  false,
	}
)

// RegexOptions impact the runtime and parsing behavior
// for each specific regex.  They are setable in code as well
// as in the regex pattern itself.
type RegexOptions int32

func ( RegexOptions) ( *compileConfig) {
	.regexOptions |= 
}

const (
	None                    RegexOptions = 0x0
	IgnoreCase              RegexOptions = 0x0001 // "i"
	Multiline               RegexOptions = 0x0002 // "m"
	ExplicitCapture         RegexOptions = 0x0004 // "n"
	Singleline              RegexOptions = 0x0010 // "s"
	IgnorePatternWhitespace RegexOptions = 0x0020 // "x"
	RightToLeft             RegexOptions = 0x0040 // "r"
	// ECMAScript attempts to follow ECMAScript regex behavior rather than C# RegexOptions.ECMAScript compatibility.
	ECMAScript RegexOptions = 0x0100 // "e"
	RE2        RegexOptions = 0x0200 // RE2 (regexp package) compatibility mode
	Unicode    RegexOptions = 0x0400 // "u"
)

// OptimizationOptions controls runtime limits, optional caches, and compile-time fast paths.
//
// For MaxBacktrackingStackSize, negative values allow unbounded growth.
// For replacement data cache size fields, 0 disables persistent retention and
// -1 means unbounded. For pooled buffer cache size fields, 0 disables pooling
// and -1 allows all built-in size classes.
// Defaults are intentionally bounded so Compile is safe for mixed-cardinality inputs.
type OptimizationOptions struct {
	// MaxBacktrackingStackSize limits the number of integer slots used by a match's backtracking stack.
	// Negative values disable the limit.
	MaxBacktrackingStackSize int
	// MaxCachedRuneBufferLength limits retained string-to-rune buffers in the shared size-classed pool.
	MaxCachedRuneBufferLength int
	// MaxCachedReplaceBufferLength limits retained replacement output buffers in the shared size-classed pool.
	MaxCachedReplaceBufferLength int
	// MaxCachedReplacerDataEntries limits the number of parsed replacement patterns cached per Regexp.
	MaxCachedReplacerDataEntries int
	// MaxCachedReplacerDataBytes skips caching replacement patterns longer than this many bytes.
	MaxCachedReplacerDataBytes int
	// DisableCharClassASCIIBitmap disables compile-time ASCII bitmap construction for character classes.
	DisableCharClassASCIIBitmap bool
}

// CompileOption configures Compile and MustCompile.
type CompileOption interface {
	applyCompileOption(*compileConfig)
}

type compileConfig struct {
	regexOptions         RegexOptions
	optimizations        OptimizationOptions
	codeGen              bool
	debug                bool
	maintainCaptureOrder bool
}

type compileOptionFunc func(*compileConfig)

func ( compileOptionFunc) ( *compileConfig) {
	()
}

func ( OptimizationOptions) ( string) bool {
	if .MaxCachedReplacerDataEntries == 0 {
		return false
	}
	return keepCacheBytes(.MaxCachedReplacerDataBytes, len())
}

func keepCacheBytes(,  int) bool {
	if  < 0 {
		return true
	}
	return  > 0 &&  <= 
}

func newCompileConfig( []CompileOption) compileConfig {
	 := compileConfig{
		optimizations: DefaultOptimizationOptions,
	}
	for ,  := range  {
		if  != nil {
			.applyCompileOption(&)
		}
	}
	return 
}

// OptionMaxBacktrackingStackSize limits the number of integer slots used by a match's backtracking stack.
// Negative values disable the limit. A match that exceeds the limit returns ErrBacktrackingStackLimit.
func ( int) CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.MaxBacktrackingStackSize = 
	})
}

// OptionMaxCachedRuneBufferLength limits retained string-to-rune buffers in the shared size-classed pool.
func ( int) CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.MaxCachedRuneBufferLength = 
	})
}

// OptionMaxCachedReplaceBufferLength limits retained replacement output buffers in the shared size-classed pool.
func ( int) CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.MaxCachedReplaceBufferLength = 
	})
}

// OptionMaxCachedReplacerDataEntries limits parsed replacement patterns cached per Regexp.
func ( int) CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.MaxCachedReplacerDataEntries = 
	})
}

// OptionMaxCachedReplacerDataBytes skips caching replacement patterns longer than n bytes.
func ( int) CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.MaxCachedReplacerDataBytes = 
	})
}

// OptionDisableCharClassASCIIBitmap disables compile-time ASCII bitmaps for character classes.
func () CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.optimizations.DisableCharClassASCIIBitmap = true
	})
}

// OptionIsCodeGen enables more expensive compile-time analysis intended for regexp2cg generated engines.
func () CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.codeGen = true
	})
}

// OptionDebug enables debug output and runner tracing for the compiled regexp.
func () CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.debug = true
	})
}

// OptionMaintainCaptureOrder assigns named and unnamed capture slots in pattern order.
func () CompileOption {
	return compileOptionFunc(func( *compileConfig) {
		.maintainCaptureOrder = true
	})
}