import six
import json


def format_command(cmd, shell=False):
    """
    Converts a command line to the notation as used in a Dockerfile ``CMD`` and ``ENTRYPOINT`` command. In shell
    notation, this returns a simple string, whereas by default it returns a JSON-list format with the command and
    arguments.

    :param cmd: Command line as a string or tuple.
    :type cmd: unicode, string, or tuple
    :param shell: Use the notation so that Docker runs the command in a shell. Default is ``False``.
    :type shell: bool
    :return: The command string.
    :rtype: unicode
    """

    def _split_cmd():
        line = None
        for part in cmd.split(' '):
            line = part if line is None else ' '.join((line, part))
            if part[-1] != '\\':
                yield line
                line = None
        if line is not None:
            yield line

    if cmd in ([], ''):
        return '[]'
    if shell:
        if isinstance(cmd, (list, tuple)):
            return ' '.join(cmd)
        elif isinstance(cmd, six.string_types):
            return cmd
    else:
        if isinstance(cmd, (list, tuple)):
            return json.dumps(cmd, encoding='utf-8')
        elif isinstance(cmd, six.string_types):
            return json.dumps([c for c in _split_cmd()], encoding='utf-8')
    raise ValueError("Invalid type of command string or sequence: {0}".format(cmd))