use super::{RuleConfigurability, RuleDefaultSeverity, RuleDefinition, RuleLanguage, RuleStatus};

pub(crate) const RULE_DEFINITIONS: &[RuleDefinition] = &[
    RuleDefinition {
        id: "aws_credential_hardcoded",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Error,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`credentials.NewStaticCredentials(\"AKID...\", \"secret...\", \"\")` with literal access keys",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "aws_session_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`session.NewSession()` or `config.LoadDefaultConfig(ctx)` inside handler functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "cobra_flag_lookup_in_run",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`cmd.Flags().GetString(\"flag\")` inside `RunE` when the flag could be bound to a variable with `StringVar`",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "config_file_read_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`os.ReadFile(\"config.json\")` or `viper.ReadInConfig()` inside handler or loop code",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "dynamodb_scan_in_handler",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`dynamodb.Scan` in request handler functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "env_parsing_repeated_in_init",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "multiple `os.Getenv` + `strconv.Atoi` / `strconv.ParseBool` chains that could be replaced with a config struct + `envconfig` or `env` library",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "error_logged_and_returned",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`log.Error(err); return err` or `logger.Error(\"failed\", zap.Error(err)); return fmt.Errorf(\"failed: %w\", err)` \u{2014} logging the error then returning it",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "grpc_context_not_propagated",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "gRPC handler methods that create new `context.Background()` instead of using the stream/request context",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "grpc_dial_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`grpc.Dial(addr, opts...)` or `grpc.NewClient(addr, opts...)` inside handler functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "grpc_large_message_without_streaming",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "unary RPC handlers returning or receiving messages > 4MB (inferred from large slice/struct serialization patterns)",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "grpc_no_keepalive_config",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`grpc.NewServer()` without keepalive server parameters in long-running services",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "grpc_unary_interceptor_per_rpc",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "interceptor/middleware construction inside RPC handler methods instead of at server setup",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "log_level_check_after_format",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`zap.S().Debugf(\"expensive %v\", computeDebug())` or `logrus.Debugf(\"data: %v\", expensiveCall())` where the expensive computation happens regardless of log level",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "log_printf_for_production",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`log.Printf` (stdlib) usage in web service handler code",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "logger_created_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`zap.NewProduction()` or `logrus.New()` inside handler functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "os_getenv_in_hot_path",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`os.Getenv(\"KEY\")` inside handler functions or loops",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "prometheus_counter_created_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`prometheus.NewCounter(prometheus.CounterOpts{...})` inside handler functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "prometheus_high_cardinality_labels",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`counter.WithLabelValues(userId)` or `histogram.WithLabelValues(requestPath)` where label values appear to come from user IDs, request paths, or other high-cardinality sources",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "prometheus_observe_without_timer",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "manual `time.Since(start).Seconds()` + `histogram.Observe(duration)` patterns when `prometheus.NewTimer` would be safer",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "prometheus_unregistered_metric",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "metrics created with `prometheus.NewCounter`/`NewHistogram` that are never registered with `prometheus.MustRegister` or `promauto`",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "redis_connection_per_request",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`redis.NewClient(&redis.Options{...})` inside handler/request functions",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "redis_get_set_without_pipeline",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "multiple sequential `rdb.Get(ctx, key)` or `rdb.Set(ctx, key, val, ...)` calls in the same function without pipeline",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "redis_keys_command_in_handler",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`rdb.Keys(ctx, pattern)` in handler or loop code",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "redis_large_value_without_compression",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`rdb.Set(ctx, key, largePayload, ...)` where `largePayload` is the result of `json.Marshal` on a large struct or slice, without visible compression",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "redis_no_ttl_on_cache_keys",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`rdb.Set(ctx, key, val, 0)` or `rdb.Set(ctx, key, val, redis.KeepTTL)` for cache-like keys without TTL",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "s3_getobject_without_range",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`s3.GetObject` downloading full objects when only partial data is needed (inferred from subsequent `io.LimitReader` or partial reads)",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "s3_listobjects_without_pagination",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`s3.ListObjectsV2` without `MaxKeys` or pagination in handler code",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "string_format_in_structured_logger",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Info,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`logger.Info(fmt.Sprintf(\"user %s logged in\", user))` instead of structured fields",
        binding_location: super::bindings::GO_LIBRARY,
    },
    RuleDefinition {
        id: "viper_get_in_hot_path",
        language: RuleLanguage::Go,
        family: "library",
        default_severity: RuleDefaultSeverity::Warning,
        status: RuleStatus::Stable,
        configurability: &[
            RuleConfigurability::Disable,
            RuleConfigurability::Ignore,
            RuleConfigurability::SeverityOverride,
        ],
        description: "`viper.GetString(\"key\")` or `viper.GetInt(\"key\")` inside handler functions or loops",
        binding_location: super::bindings::GO_LIBRARY,
    },
];
