import io
import os

from graphql_relay.node.node import from_global_id

"""Script defined to create helper functions for graphql schema."""


# https://medium.com/@jamesvaresamuel/mutation-and-query-in-graphql-using-python-django-part-2-79d9852a1092
def get_object(object_name, relay_id, otherwise=None):
    try:
        return object_name.objects.get(pk=from_global_id(relay_id)[1])
    except:
        return otherwise


def update_create_instance(instance, args, exception=['id']):
    if instance:
        [setattr(instance, key, value) for key, value in args.items() if key not in exception]

    # caution if you literally cloned this project, then be sure to have
    # elasticsearch running as every saved instance must go through
    # elasticsearch according to the way this project is configured.
    instance.save()

    return instance


def get_errors(e):
    # transform django errors to redux errors
    # django: {"key1": [value1], {"key2": [value2]}}
    # redux: ["key1", "value1", "key2", "value2"]
    fields = e.message_dict.keys()
    messages = ['; '.join(m) for m in e.message_dict.values()]
    errors = [i for pair in zip(fields, messages) for i in pair]
    return errors


def get_graphql_query(filename):
    from django.conf import settings

    with io.open(os.path.join(settings.GRAPHQL_QUERIES_DIR, filename)) as f:
        query = f.read()

    return query


def get_graphql_mutation(filename):
    """
    Get the GraphQL mutation from the mutation directory
    :param filename: the filename of the mutation
    :return: the mutation
    """

    from django.conf import settings

    with io.open(os.path.join(settings.GRAPHQL_MUTATIONS_DIR, filename)) as f:
        mutation = f.read()

    return mutation


def get_by_id(model, **kwargs):
    id = kwargs.get('id')

    return get_object(model, id) if id is not None else None


def get_by_id_or_slug(model, **kwargs):
    slug = kwargs.get('slug')
    id = kwargs.get('id')

    if id is not None:
        return get_object(model, id)
    if slug is not None:
        return model.objects.get(slug=slug)
    return None
