package click.kamil.springstatemachineexporter.analysis.service;

/**
 * Recognizes JDK functional interface parameters used as delayed event providers
 * ({@code Supplier.get()}, etc.) in call-graph argument tracing.
 */
public final class FunctionalInterfaceTypes {

    private FunctionalInterfaceTypes() {
    }

    public static boolean isFunctionalInterface(String typeName) {
        if (typeName == null || typeName.isBlank()) {
            return false;
        }
        String simple = typeName.contains(".") ? typeName.substring(typeName.lastIndexOf('.') + 1) : typeName;
        if (simple.contains("<")) {
            simple = simple.substring(0, simple.indexOf('<'));
        }
        return "Supplier".equals(simple) || "Function".equals(simple) || "Callable".equals(simple);
    }

    public static boolean isLambdaArgument(String argValue) {
        if (argValue == null) {
            return false;
        }
        String trimmed = argValue.trim();
        return trimmed.contains("->")
                && (trimmed.startsWith("(") || trimmed.matches("^\\w+\\s*->.*"));
    }

    /**
     * When the caller passes a lambda or enum literal into a functional parameter, skip
     * incompatible-type rejection between {@code Supplier<T>} and resolved {@code T}.
     */
    public static boolean isProvablyResolvedCallSiteArgument(String argValue, String expectedType) {
        if (argValue == null || argValue.isBlank() || expectedType == null) {
            return false;
        }
        if (!isFunctionalInterface(expectedType)) {
            return false;
        }
        if (looksLikeEnumConstant(argValue)) {
            return true;
        }
        return isLambdaArgument(argValue);
    }

    static boolean looksLikeEnumConstant(String value) {
        if (value == null || value.isBlank()) {
            return false;
        }
        String name = value.contains(".") ? value.substring(value.lastIndexOf('.') + 1) : value;
        return name.matches("[A-Z_][A-Z0-9_]*");
    }
}
