package error_wrapper

import "regexp"

// CommonChangefeedErr classifies TiCDC kernel error codes that represent
// user-configuration mistakes rather than system failures.
type CommonChangefeedErr string

const (
	ErrChangefeedNotCommonErr             CommonChangefeedErr = "NotCommonErr"
	ErrChangefeedKafkaInvalidConfig       CommonChangefeedErr = "KafkaInvalidConfig"
	ErrChangefeedKafkaInvalidPartitionNum CommonChangefeedErr = "KafkaInvalidPartitionNum"
	ErrChangefeedKafkaTopicExprInvalid    CommonChangefeedErr = "KafkaTopicExprInvalid"
	ErrChangefeedTableIneligible          CommonChangefeedErr = "TableIneligible"
	ErrChangefeedAPIInvalidParam          CommonChangefeedErr = "InvalidParam"
	ErrChangefeedStartTsBeforeGC          CommonChangefeedErr = "StartTsBeforeGC"
	ErrChangefeedKafkaNewProducer         CommonChangefeedErr = "KafkaNewProducer" // wraps ErrKafkaInvalidPartitionNum / ErrAvroSchemaAPIError
)

// cdcUserErrPatterns maps pre-compiled regex patterns to CommonChangefeedErr values.
// Order matters: inner/specific error codes are checked before their wrapper codes.
// Pre-compiled at init time to avoid regex compilation overhead on every call.
var cdcUserErrPatterns = []struct {
	pattern *regexp.Regexp
	errType CommonChangefeedErr
}{
	{regexp.MustCompile("ErrKafkaInvalidPartitionNum"), ErrChangefeedKafkaInvalidPartitionNum},
	{regexp.MustCompile("ErrKafkaInvalidConfig"), ErrChangefeedKafkaInvalidConfig},
	{regexp.MustCompile("ErrKafkaTopicExprInvalid"), ErrChangefeedKafkaTopicExprInvalid},
	{regexp.MustCompile("ErrTableIneligible"), ErrChangefeedTableIneligible},
	{regexp.MustCompile("ErrAPIInvalidParam"), ErrChangefeedAPIInvalidParam},
	{regexp.MustCompile("ErrStartTsBeforeGC"), ErrChangefeedStartTsBeforeGC},
	{regexp.MustCompile("ErrKafkaNewProducer"), ErrChangefeedKafkaNewProducer},
}

// ClassifyChangefeedError inspects a raw kernel error message and returns the
// matching CommonChangefeedErr, or ErrChangefeedNotCommonErr when none match.
func ClassifyChangefeedError(errMsg string) CommonChangefeedErr {
	for _, entry := range cdcUserErrPatterns {
		if entry.pattern.MatchString(errMsg) {
			return entry.errType
		}
	}
	return ErrChangefeedNotCommonErr
}

// ChangefeedErrType returns the err_type label value for Prometheus metrics.
// Returns "SystemError" for unknown/system failures so alert rules can use
// err_type="SystemError" for critical alerts and err_type!="SystemError" for
// user-configuration noise.
func ChangefeedErrType(errMsg string) string {
	t := ClassifyChangefeedError(errMsg)
	if t == ErrChangefeedNotCommonErr {
		return "SystemError"
	}
	return string(t)
}
