package com.cameleer.server.app.alerting.notify;

import com.cameleer.server.core.alerting.AlertInstance;
import com.cameleer.server.core.alerting.AlertRule;
import com.cameleer.server.core.alerting.SilenceMatcher;
import org.springframework.stereotype.Component;

/**
 * Evaluates whether an active silence matches an alert instance at notification-dispatch time.
 * <p>
 * Each non-null field on the matcher is an additional AND constraint. A null field is a wildcard.
 * Matching is purely in-process — no I/O.
 */
@Component
public class SilenceMatcherService {

    /**
     * Returns {@code true} if the silence covers this alert instance.
     *
     * @param matcher  the silence's matching spec (never null)
     * @param instance the alert instance to test (never null)
     * @param rule     the alert rule; may be null when the rule was deleted after instance creation.
     *                 Scope-based matchers (appSlug, routeId, agentId) return false when rule is null
     *                 because the scope cannot be verified.
     */
    public boolean matches(SilenceMatcher matcher, AlertInstance instance, AlertRule rule) {
        // ruleId constraint
        if (matcher.ruleId() != null && !matcher.ruleId().equals(instance.ruleId())) {
            return false;
        }

        // severity constraint
        if (matcher.severity() != null && matcher.severity() != instance.severity()) {
            return false;
        }

        // scope-based constraints require the rule to derive scope from
        boolean needsScope = matcher.appSlug() != null || matcher.routeId() != null || matcher.agentId() != null;
        if (needsScope && rule == null) {
            return false;
        }

        if (rule != null && rule.condition() != null) {
            var scope = rule.condition().scope();
            if (matcher.appSlug() != null && !matcher.appSlug().equals(scope.appSlug())) {
                return false;
            }
            if (matcher.routeId() != null && !matcher.routeId().equals(scope.routeId())) {
                return false;
            }
            if (matcher.agentId() != null && !matcher.agentId().equals(scope.agentId())) {
                return false;
            }
        }

        return true;
    }
}
