#!/usr/bin/env python

r"""
This module provides argument manipulation functions like pop_arg.
"""

import gen_print as gp
import collections


def pop_arg(default=None, *args, **kwargs):
    r"""
    Pop a named argument from the args/kwargs and return a tuple consisting of the argument value, the
    modified args and the modified kwargs.

    The name of the argument is determined automatically by this function by examining the source code which
    calls it (see examples below).  If no suitable argument can be found, the default value passed to this
    function will be returned as the argument value.  This function is useful for wrapper functions that wish
    to process arguments in some way before calling subordinate function.

    Examples:

    Given this code:

    def func1(*args, **kwargs):

        last_name, args, kwargs = pop_arg('Doe', *args, **kwargs)
        some_function(last_name.capitalize(), *args, **kwargs)

    Consider this call to func1:

    func1('Johnson', ssn='111-11-1111')

    The pop_arg in func1 would return the following:

        'Johnson', [], {'ssn': "111-11-1111"}

    Notice that the 'args' value returned is an empty list. Since last_name was assumed to be the first
    positional argument, it was popped from args.

    Now consider this call to func1:

    func1(last_name='Johnson', ssn='111-11-1111')

    The pop_arg in func1 would return the same last_name value as in the previous example.  The only
    difference being that the last_name value was popped from kwargs rather than from args.

    Description of argument(s):
    default                         The value to return if the named argument is not present in args/kwargs.
    args                            The positional arguments passed to the calling function.
    kwargs                          The keyword arguments passed to the calling function.
    """

    # Retrieve the argument name by examining the source code.
    arg_name = gp.get_arg_name(None, arg_num=-3, stack_frame_ix=2)
    if arg_name in kwargs:
        arg_value = kwargs.pop(arg_name)
    else:
        # Convert args from a tuple to a list.
        args = list(args)
        if args:
            arg_value = args.pop(0)
        else:
            arg_value = default

    return arg_value, args, kwargs


def source_to_object(value):
    r"""
    Evaluate string value as python source code and return the resulting object.

    If value is NOT a string or can not be interpreted as a python source object definition, simply return
    value.

    The idea is to convert python object definition source code (e.g. for lists, dictionaries, tuples, etc.)
    into an object.

    Example:

    Note that this first example is a special case in that it is a short-cut for specifying a
    collections.OrderedDict.

    result = source_to_object("[('one', 1), ('two', 2), ('three', 3)]")

    The result is a collections.OrderedDict object:

    result:
      [one]:                     1
      [two]:                     2
      [three]:                   3

    This is a short-cut for the long form shown here:

    result = source_to_object("collections.OrderedDict([
        ('one', 1),
        ('two', 2),
        ('three', 3)])")

    Also note that support for this special-case short-cut precludes the possibility of interpreting such a
    string as a list of tuples.

    Example:

    In this example, the result will be a list:

    result = source_to_object("[1, 2, 3]")

    result:
      result[0]:                 1
      result[1]:                 2
      result[2]:                 3

    Example:

    In this example, the value passed to this function is not a string, so it is simply returned.

    result = source_to_object(1)

    More examples:
    result = source_to_object("dict(one=1, two=2, three=3)")
    result = source_to_object("{'one':1, 'two':2, 'three':3}")
    result = source_to_object(True)
    etc.

    Description of argument(s):
    value                           If value is a string, it will be evaluated as a python statement.  If the
                                    statement is valid, the resulting object will be returned.  In all other
                                    cases, the value will simply be returned.
    """

    if type(value) not in gp.get_string_types():
        return value

    # Strip white space prior to attempting to interpret the string as python code.
    value = value.strip()

    # Try special case of collections.OrderedDict which accepts a list of tuple pairs.
    if value.startswith("[("):
        try:
            return eval("collections.OrderedDict(" + value + ")")
        except (TypeError, NameError, ValueError):
            pass

    try:
        return eval(value)
    except (NameError, SyntaxError):
        pass

    return value


def args_to_objects(args):
    r"""
    Run source_to_object() on each element in args and return the result.

    Description of argument(s):
    args                            A type of dictionary, list, set, tuple or simple object whose elements
                                    are to be converted via a call to source_to_object().
    """

    type_of_dict = gp.is_dict(args)
    if type_of_dict:
        if type_of_dict == gp.dict_type():
            return {k: source_to_object(v) for (k, v) in args.items()}
        elif type_of_dict == gp.ordered_dict_type():
            return collections.OrderedDict((k, v) for (k, v) in args.items())
        elif type_of_dict == gp.dot_dict_type():
            return DotDict((k, v) for (k, v) in args.items())
        elif type_of_dict == gp.normalized_dict_type():
            return NormalizedDict((k, v) for (k, v) in args.items())
    # Assume args is list, tuple or set.
    if type(args) in (list, set):
        return [source_to_object(arg) for arg in args]
    elif type(args) is tuple:
        return tuple([source_to_object(arg) for arg in args])

    return source_to_object(args)
