# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import datafusion
import datafusion.functions
import datafusion.object_store
import datafusion.substrait
import pytest

# EnumType introduced in 3.11. 3.10 and prior it was called EnumMeta.
try:
    from enum import EnumType
except ImportError:
    from enum import EnumMeta as EnumType


# Internal methods a wrapper calls but does not re-export. Add to this only
# when the method exists to serve a public wrapper, never to silence a genuine
# gap in coverage.
PRIVATE_SUPPORT_METHODS = frozenset(
    {
        # The two steps of SessionContext.with_extensions: install the
        # codecs, then run the planner hooks and commit everything the
        # bundles declared.
        "_install_extension_codecs",
        "_commit_extensions",
        # Physical optimizer rules, split so the capsule import happens while
        # the call can still fail without leaving the session half-installed.
        "_resolve_extension_physical_optimizer_rules",
        "_install_extension_physical_optimizer_rules",
    }
)


def _check_enum_exports(internal_obj, wrapped_obj) -> None:
    """Check that all enum values are present in wrapped object."""
    expected_values = [v for v in dir(internal_obj) if not v.startswith("__")]
    for value in expected_values:
        assert value in dir(wrapped_obj)


def _check_list_attribute(internal_attr, wrapped_attr) -> None:
    """Check that list attributes match between internal and wrapped objects."""
    assert isinstance(wrapped_attr, list)

    # We have cases like __all__ that are a list and we want to be certain that
    # every value in the list in the internal object is also in the wrapper list
    for val in internal_attr:
        if isinstance(val, str) and val.startswith("Raw"):
            assert val[3:] in wrapped_attr
        else:
            assert val in wrapped_attr


def missing_exports(internal_obj, wrapped_obj) -> None:
    """
    Identify if any of the rust exposted structs or functions do not have wrappers.

    Special handling for:
    - Raw* classes: Internal implementation details that shouldn't be exposed
    - _global_ctx: Internal implementation detail
    - __self__, __class__, __repr__: Python special attributes
    """
    # Special case enums - EnumType overrides a some of the internal functions,
    # so check all of the values exist and move on
    if isinstance(wrapped_obj, EnumType):
        _check_enum_exports(internal_obj, wrapped_obj)
        return

    if "__repr__" in internal_obj.__dict__ and "__repr__" not in wrapped_obj.__dict__:
        pytest.fail(f"Missing __repr__: {internal_obj.__name__}")

    for internal_attr_name in dir(internal_obj):
        # Private support methods that exist only for a wrapper to call, so
        # they are not part of the public surface and need no wrapper of their
        # own. Listed rather than matched by leading underscore, which would
        # also excuse names like `_repr_html_` that a wrapper does have to
        # provide.
        if internal_attr_name in PRIVATE_SUPPORT_METHODS:
            continue

        wrapped_attr_name = internal_attr_name.removeprefix("Raw")

        assert wrapped_attr_name in dir(wrapped_obj)

        internal_attr = getattr(internal_obj, internal_attr_name)
        wrapped_attr = getattr(wrapped_obj, wrapped_attr_name)

        # There are some auto generated attributes that can be None, such as
        # __kwdefaults__ and __doc__. As long as these are None on the internal
        # object, it's okay to skip them. However if they do exist on the internal
        # object they must also exist on the wrapped object.
        if internal_attr is not None and wrapped_attr is None:
            pytest.fail(f"Missing attribute: {internal_attr_name}")

        if internal_attr_name in ["__self__", "__class__"]:
            continue

        if isinstance(internal_attr, list):
            _check_list_attribute(internal_attr, wrapped_attr)
        elif hasattr(internal_attr, "__dict__"):
            # Check all submodules recursively
            missing_exports(internal_attr, wrapped_attr)


def test_datafusion_missing_exports() -> None:
    """Check for any missing python exports.

    This test verifies that every exposed class, attribute,
    and function in the internal (pyo3) module - datafusion._internal
    is also exposed in our python wrappers - datafusion -
    i.e., the ones exposed to the public.
    """
    missing_exports(datafusion._internal, datafusion)
