import shlex


def get_curlbomb_command(settings, unwrapped=None):
    """Get the curlbomb command

    Inspects settings['unwrapped'] and returns the full curlbomb
    command if True. A wrapper script is returned in the default case.
    
    Alternatively, you can pass unwrapped=True to force getting the
    unwrapped script.
    """
    # Pin tls cert to client command if we are using curl, --ssl, and --pin
    pin_settings=""
    if settings['http_fetcher'].startswith("curl") and \
       settings['ssl'] is not False and settings['pin'] is True:
        pin_settings = " -k --pinnedpubkey 'sha256//{}'".format(settings['ssl_hash'])

    if (settings['unwrapped'] and unwrapped is not False) or unwrapped is True:
        # Get the full unwrapped command:
        knock = ""
        if settings['require_knock']:
            if settings.get('require_knock_from_environment', False):
                # Don't output the actual knock code, but the shell variable name:
                k = "$KNOCK"
            else:
                k = settings['knock']
            if settings['http_fetcher'].startswith("wget"):
                knock = ' --header="X-knock: {}"'.format(k)
            else:
                knock = ' -H "X-knock: {}"'.format(k)

        hostname_header = ""
        if settings['require_hostname_header']:
            if settings['http_fetcher'].startswith("wget"):
                hostname_header = ' --header="X-hostname: $(hostname)"'
            else:
                hostname_header = ' -H "X-hostname: $(hostname)"'

        url = "http{ssl}://{host}:{port}/r{knock}{hostname_header}".format(
            ssl="s" if settings['ssl'] is not False else "",
            host=settings['display_host'],
            port=settings['display_port'],
            knock=knock,
            hostname_header=hostname_header
        )
        stream_url = "http{ssl}://{host}:{port}/s{knock}{hostname_header}".format(
            ssl="s" if settings['ssl'] is not False else "",
            host=settings['display_host'],
            port=settings['display_port'],
            knock=knock,
            hostname_header=hostname_header
        )

        decrypter = ""
        if settings['client_decrypt']:
            decrypter = " | gpg -d"

        logger = ""
        if settings['client_logging']:
            logger = " | tee curlbomb.log"

        if settings['receive_postbacks']:
            callback_cmd="curl{pin_settings} -T - {stream_url}"
            if settings['client_quiet']:
                callback_cmd = " | " + callback_cmd
            else:
                callback_cmd = " | tee >({cmd})".format(cmd=callback_cmd)
            if settings['wget']:
                callback_cmd = (
                    ' && wget -q -O - --post-data="wget post-back finished. '
                    'wget can\'t stream the client output like curl can though '
                    ':(\r\n" {stream_url}')
            logger += callback_cmd.format(
                stream_url=stream_url,
                pin_settings=pin_settings
                )
        
        if settings['shell_command'] is None or settings['survey']:
            cmd = "{http_fetcher}{pin_settings} {url}{decrypter}{logger}".\
                  format(
                      http_fetcher=settings['http_fetcher'],
                      url=url,
                      pin_settings=pin_settings,
                      decrypter=decrypter,
                      logger=logger)
        else:
            cmd = "{shell_command} <({http_fetcher}{pin_settings} {url}{decrypter}){logger}"
            if settings['pipe_to_shell_command']:
                # If we don't care about receiving client output, pipe
                # it rather than redirecting. This is needed for
                # interactive scripts:
                cmd = "{http_fetcher}{pin_settings} {url} | {shell_command}{logger}"
            cmd = cmd.format(
                shell_command=settings['shell_command'],
                http_fetcher=settings['http_fetcher'],
                pin_settings=pin_settings,
                url=url,
                decrypter=decrypter,
                logger=logger)

        return cmd
    else:
        # Get the wrapped version:
        if settings['survey']:
            if settings['require_knock']:
                if settings['http_fetcher'].startswith("wget"):
                    knock_header = ' --header="X-knock: {}"'.format(settings['knock'])
                else:
                    knock_header = ' -H "X-knock: {}"'.format(settings['knock'])
            else:
                knock_header=''
            cmd = "{http_fetcher}{pin_settings} http{ssl}://{host}:{port}/r" + knock_header
        else:
            cmd = "{knock}bash <({http_fetcher}{pin_settings} http{ssl}://{host}:{port})"

        return cmd.format(
            http_fetcher=settings['http_fetcher'],
            ssl="s" if settings['ssl'] is not False else "",
            host=settings['display_host'],
            port=settings['display_port'],
            pin_settings=pin_settings,
            knock="KNOCK={} ".format(
                shlex.quote(settings['knock'])) if settings['require_knock'] else ''
        )