from typing import Dict, Union

from graphql import (
    GraphQLBoolean,
    GraphQLFloat,
    GraphQLInputField,
    GraphQLInt,
    GraphQLList,
    GraphQLNonNull,
    GraphQLScalarType,
    GraphQLString,
)
from sqlalchemy import ARRAY, Boolean, Float, Integer
from sqlalchemy.dialects.postgresql import ARRAY as PGARRAY
from sqlalchemy.types import TypeEngine


def get_graphql_type_from_column(column_type: TypeEngine) -> Union[GraphQLScalarType, GraphQLList]:
    if isinstance(column_type, Integer):
        return GraphQLInt

    if isinstance(column_type, Float):
        return GraphQLFloat

    if isinstance(column_type, Boolean):
        return GraphQLBoolean

    if isinstance(column_type, (ARRAY, PGARRAY)):
        return GraphQLList(get_graphql_type_from_column(column_type.item_type))

    return GraphQLString


def get_base_comparison_fields(graphql_type: Union[GraphQLScalarType, GraphQLList]) -> Dict[str, GraphQLInputField]:
    return {
        "_eq": GraphQLInputField(graphql_type),
        "_neq": GraphQLInputField(graphql_type),
        "_in": GraphQLInputField(GraphQLList(GraphQLNonNull(graphql_type))),
        "_nin": GraphQLInputField(GraphQLList(GraphQLNonNull(graphql_type))),
        "_lt": GraphQLInputField(graphql_type),
        "_gt": GraphQLInputField(graphql_type),
        "_gte": GraphQLInputField(graphql_type),
        "_lte": GraphQLInputField(graphql_type),
        "_is_null": GraphQLInputField(GraphQLBoolean),
    }


def get_string_comparison_fields() -> Dict[str, GraphQLInputField]:
    return {"_like": GraphQLInputField(GraphQLString), "_nlike": GraphQLInputField(GraphQLString)}

[((979, 1010), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (996, 1010), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1028, 1059), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (1045, 1059), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1231, 1262), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (1248, 1262), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1279, 1310), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (1296, 1310), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1328, 1359), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (1345, 1359), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1377, 1408), 'graphql.GraphQLInputField', 'GraphQLInputField', (['graphql_type'], {}), '(graphql_type)\n', (1394, 1408), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1430, 1463), 'graphql.GraphQLInputField', 'GraphQLInputField', (['GraphQLBoolean'], {}), '(GraphQLBoolean)\n', (1447, 1463), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1562, 1594), 'graphql.GraphQLInputField', 'GraphQLInputField', (['GraphQLString'], {}), '(GraphQLString)\n', (1579, 1594), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1606, 1638), 'graphql.GraphQLInputField', 'GraphQLInputField', (['GraphQLString'], {}), '(GraphQLString)\n', (1623, 1638), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1106, 1134), 'graphql.GraphQLNonNull', 'GraphQLNonNull', (['graphql_type'], {}), '(graphql_type)\n', (1120, 1134), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((1184, 1212), 'graphql.GraphQLNonNull', 'GraphQLNonNull', (['graphql_type'], {}), '(graphql_type)\n', (1198, 1212), False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n')]