package click.kamil.springstatemachineexporter.analysis.pipeline;

import java.util.Locale;
import java.util.Set;

/**
 * Central registry for reactive/factory unwrap and passthrough method names used during constant extraction.
 */
public final class LibraryUnwrapRegistry {

    private static final Set<String> UNWRAP_RECEIVER_TYPES = Set.of(
            "Optional", "Stream", "List", "Set", "Arrays", "Objects", "Mono", "Flux");

    private static final Set<String> UNWRAP_METHOD_NAMES = Set.of(
            "of", "ofEntries", "asList", "entry", "just", "withPayload", "success");

    private static final String[] STOP_UNWRAP_PREFIXES = {
            "map", "parse", "convert", "to", "resolve", "build", "create", "from",
            "transform", "translate", "derive", "determine", "calculate", "decode",
            "extract", "get", "find", "validate"
    };

    private LibraryUnwrapRegistry() {
    }

    public static boolean isUnwrapReceiverType(String receiverExpressionText) {
        return receiverExpressionText != null && UNWRAP_RECEIVER_TYPES.contains(receiverExpressionText);
    }

    public static boolean isUnwrapMethodName(String methodName) {
        return methodName != null && UNWRAP_METHOD_NAMES.contains(methodName);
    }

    public static boolean shouldStopUnwrap(String methodName) {
        if (methodName == null) {
            return true;
        }
        String lowerName = methodName.toLowerCase(Locale.ROOT);
        for (String prefix : STOP_UNWRAP_PREFIXES) {
            if (lowerName.startsWith(prefix)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isEventSetterMethodName(String methodName) {
        if (methodName == null) {
            return false;
        }
        return "event".equalsIgnoreCase(methodName)
                || "type".equalsIgnoreCase(methodName)
                || "eventType".equalsIgnoreCase(methodName);
    }

    public static boolean isHeaderSetterMethodName(String methodName) {
        return "setHeader".equals(methodName);
    }
}
