# 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


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__: 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):
        expected_values = [v for v in dir(internal_obj) if not v.startswith("__")]
        for value in expected_values:
            assert value in dir(wrapped_obj)
        return

    for internal_attr_name in dir(internal_obj):
        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):
            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
        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)
