from typing import Any, List
from depth.dotget.core import get

def all_match(collection: List[Any], path: str, value: Any) -> bool:
    """
    Checks if all documents in the collection have the specified value at the given path.
    
    This is the universal quantifier for collections - returns True only if every
    document in the collection has the specified value at the path.
    
    Args:
        collection: List of documents to check
        path: Dot notation path to check in each document
        value: Value to match against
        
    Returns:
        True if all documents have the value at the path, False otherwise
        Empty collections return True (vacuous truth)
        
    Examples:
        >>> users = [{"name": "Alice", "active": True}, {"name": "Bob", "active": True}]
        >>> all_match(users, "active", True)
        True
        >>> users.append({"name": "Charlie", "active": False})
        >>> all_match(users, "active", True)
        False
    """
    if not collection:
        # Empty collection - all elements satisfy any predicate (vacuous truth)
        return True
    
    for doc in collection:
        try:
            if get(doc, path) != value:
                return False
        except (KeyError, IndexError, TypeError, AttributeError):
            # Path doesn't exist in this document - counts as not matching
            return False

    return True


def check(data: Any, path: str, equals: Any = None) -> bool:
    """
    Check if ALL elements in the collection at `path` match `equals`.

    This is a single-document convenience wrapper for CLI use.
    It extracts the collection at `path` from `data` using dotget,
    then checks whether every element equals `equals`.

    Args:
        data: The source document
        path: Dot notation path to a collection within data
        equals: Value to compare against

    Returns:
        True if all elements match, False otherwise
        Empty collections return True (vacuous truth)
    """
    try:
        collection = get(data, path)
    except (KeyError, IndexError, TypeError, AttributeError):
        return False

    if not isinstance(collection, list):
        return collection == equals

    if not collection:
        return True

    for item in collection:
        if item != equals and str(item) != str(equals):
            return False
    return True
