from __future__ import annotations

from collections.abc import Iterable


def ensure_required_columns_exist(
    df_columns: Iterable[str],
    required_columns: Iterable[str],
) -> list[str]:
    """
    Ensure that all required columns are present in a DataFrame.

    Args:
        df_columns: The list or index of columns in the input DataFrame.
        required_columns: The columns that must be present.

    Returns:
        A list of missing column names. If empty, all required columns are present.
    """
    df_cols = {str(c).strip() for c in df_columns}
    required = {str(c).strip() for c in required_columns}
    missing = sorted(required - df_cols)
    return missing


def validate_dataframe_columns(df, required_columns: Iterable[str]) -> None:
    """
    Validate that a DataFrame contains all required columns.

    Raises:
        ColumnValidationError: if any required column is missing.
    """
    from ..errors import ColumnValidationError  # local import to avoid circular dependency

    missing = ensure_required_columns_exist(df.columns, required_columns)
    if missing:
        raise ColumnValidationError(
            f"Missing required columns: {', '.join(missing)}"
        )
