from __future__ import annotations

import ast
import logging

import libcst as cst

log = logging.getLogger(__name__)


def validate_python_syntax(source: str) -> bool:
    """
    Check if *source* is valid Python using both ast and libcst.
    """
    try:
        ast.parse(source)
    except SyntaxError:
        return False

    try:
        module = cst.parse_module(source)
        if not module.body:
            return False
    except cst.ParserSyntaxError:
        return False

    return True


def parse_python_or_none(
    source: str,
) -> cst.Module | None:
    """
    Parse *source* into a CST module, or None on failure.
    """
    try:
        module = cst.parse_module(source)
    except cst.ParserSyntaxError:
        log.warning("Failed to parse Python source")
        return None
    if not module.body:
        return None
    return module
