# -*- coding: utf-8 -*-
"""The :program:`celery amqp` command.

.. program:: celery amqp
"""
from __future__ import absolute_import, print_function, unicode_literals

import cmd as _cmd
import pprint
import shlex
import sys
from functools import partial
from itertools import count

from kombu.utils.encoding import safe_str

from celery.bin.base import Command
from celery.five import string_t
from celery.utils.functional import padlist
from celery.utils.serialization import strtobool

__all__ = ('AMQPAdmin', 'AMQShell', 'Spec', 'amqp')

# Map to coerce strings to other types.
COERCE = {bool: strtobool}

HELP_HEADER = """
Commands
--------
""".rstrip()

EXAMPLE_TEXT = """
Example:
    -> queue.delete myqueue yes no
"""

say = partial(print, file=sys.stderr)


class Spec(object):
    """AMQP Command specification.

    Used to convert arguments to Python values and display various help
    and tool-tips.

    Arguments:
        args (Sequence): see :attr:`args`.
        returns (str): see :attr:`returns`.
    """

    #: List of arguments this command takes.
    #: Should contain ``(argument_name, argument_type)`` tuples.
    args = None

    #: Helpful human string representation of what this command returns.
    #: May be :const:`None`, to signify the return type is unknown.
    returns = None

    def __init__(self, *args, **kwargs):
        self.args = args
        self.returns = kwargs.get('returns')

    def coerce(self, index, value):
        """Coerce value for argument at index."""
        arg_info = self.args[index]
        arg_type = arg_info[1]
        # Might be a custom way to coerce the string value,
        # so look in the coercion map.
        return COERCE.get(arg_type, arg_type)(value)

    def str_args_to_python(self, arglist):
        """Process list of string arguments to values according to spec.

        Example:
            >>> spec = Spec([('queue', str), ('if_unused', bool)])
            >>> spec.str_args_to_python('pobox', 'true')
            ('pobox', True)
        """
        return tuple(
            self.coerce(index, value) for index, value in enumerate(arglist))

    def format_response(self, response):
        """Format the return value of this command in a human-friendly way."""
        if not self.returns:
            return 'ok.' if response is None else response
        if callable(self.returns):
            return self.returns(response)
        return self.returns.format(response)

    def format_arg(self, name, type, default_value=None):
        if default_value is not None:
            return '{0}:{1}'.format(name, default_value)
        return name

    def format_signature(self):
        return ' '.join(self.format_arg(*padlist(list(arg), 3))
                        for arg in self.args)


def dump_message(message):
    if message is None:
        return 'No messages in queue. basic.publish something.'