# 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 pytest
from datafusion import (
    AggregateUDF,
    DataFrame,
    ScalarUDF,
    SessionContext,
    TableProviderFactory,
    TableProviderFactoryExportable,
    functions,
)
from datafusion.common import (
    DFSchema,
)
from datafusion.expr import (
    Aggregate,
    AggregateFunction,
    Alias,
    Analyze,
    Between,
    BinaryExpr,
    Case,
    Cast,
    Column,
    CreateMemoryTable,
    CreateView,
    Distinct,
    DropTable,
    Exists,
    Explain,
    Expr,
    Extension,
    Filter,
    GroupingSet,
    HigherOrderFunction,
    ILike,
    InList,
    InSubquery,
    IsFalse,
    IsNotFalse,
    IsNotNull,
    IsNotTrue,
    IsNotUnknown,
    IsTrue,
    IsUnknown,
    Join,
    JoinConstraint,
    JoinType,
    Lambda,
    LambdaVariable,
    Like,
    Limit,
    Literal,
    Negative,
    Not,
    Partitioning,
    Placeholder,
    Projection,
    Repartition,
    ScalarSubquery,
    ScalarVariable,
    SimilarTo,
    Sort,
    Subquery,
    SubqueryAlias,
    TableScan,
    TryCast,
    Union,
)


def test_import_datafusion():
    assert datafusion.__name__ == "datafusion"


def test_datafusion_python_version():
    assert datafusion.__version__ is not None


def test_class_module_is_datafusion():
    # context
    for klass in [
        SessionContext,
    ]:
        assert klass.__module__ == "datafusion.context"

    # dataframe
    for klass in [
        DataFrame,
    ]:
        assert klass.__module__ == "datafusion.dataframe"

    # udf
    for klass in [
        AggregateUDF,
        ScalarUDF,
    ]:
        assert klass.__module__ == "datafusion.user_defined"

    # expressions
    for klass in [Expr, Column, Literal, BinaryExpr, AggregateFunction]:
        assert klass.__module__ == "datafusion.expr"

    # operators
    for klass in [
        Projection,
        TableScan,
        Aggregate,
        Sort,
        Limit,
        Filter,
        Analyze,
        Join,
        JoinType,
        JoinConstraint,
        Union,
        Like,
        ILike,
        SimilarTo,
        ScalarVariable,
        Alias,
        Not,
        IsNotNull,
        IsTrue,
        IsFalse,
        IsUnknown,
        IsNotTrue,
        IsNotFalse,
        IsNotUnknown,
        Negative,
        InList,
        Exists,
        Subquery,
        InSubquery,
        ScalarSubquery,
        GroupingSet,
        Placeholder,
        Case,
        Cast,
        TryCast,
        Between,
        SubqueryAlias,
        Explain,
        Extension,
        CreateMemoryTable,
        CreateView,
        Distinct,
        DropTable,
        Repartition,
        Partitioning,
        HigherOrderFunction,
        Lambda,
        LambdaVariable,
    ]:
        assert klass.__module__ == "datafusion.expr"

    # catalog factory types (re-exported at top level)
    for klass in [TableProviderFactory, TableProviderFactoryExportable]:
        assert klass.__module__ == "datafusion.catalog"

    # schema
    for klass in [DFSchema]:
        assert klass.__module__ == "datafusion.common"


def test_import_from_functions_submodule():
    from datafusion.functions import abs as df_abs
    from datafusion.functions import sin

    assert functions.abs is df_abs
    assert functions.sin is sin

    msg = "cannot import name 'foobar' from 'datafusion.functions'"
    with pytest.raises(ImportError, match=msg):
        from datafusion.functions import foobar  # noqa: F401


def test_classes_are_inheritable():
    class MyExecContext(SessionContext):
        pass

    class MyExpression(Expr):
        pass

    class MyDataFrame(DataFrame):
        pass
