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)}

[((36, 15, 36, 46), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(36, 33, 36, 45): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((37, 16, 37, 47), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(37, 34, 37, 46): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((40, 15, 40, 46), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(40, 33, 40, 45): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((41, 15, 41, 46), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(41, 33, 41, 45): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((42, 16, 42, 47), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(42, 34, 42, 46): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((43, 16, 43, 47), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(43, 34, 43, 46): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((44, 20, 44, 53), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(44, 38, 44, 52): 'GraphQLBoolean'}, {}), '(GraphQLBoolean)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((49, 21, 49, 53), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(49, 39, 49, 52): 'GraphQLString'}, {}), '(GraphQLString)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((49, 65, 49, 97), 'graphql.GraphQLInputField', 'GraphQLInputField', ({(49, 83, 49, 96): 'GraphQLString'}, {}), '(GraphQLString)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((38, 45, 38, 73), 'graphql.GraphQLNonNull', 'GraphQLNonNull', ({(38, 60, 38, 72): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), ((39, 46, 39, 74), 'graphql.GraphQLNonNull', 'GraphQLNonNull', ({(39, 61, 39, 73): 'graphql_type'}, {}), '(graphql_type)', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n')]