import base64
import io
import os
import os.path
import json
import shlex
import tarfile
import tempfile
import warnings
from distutils.version import StrictVersion
from datetime import datetime
from fnmatch import fnmatch

import requests
import six

from .. import constants
from .. import errors
from .. import tls
from ..types import Ulimit, LogConfig

if six.PY2:
    from urllib import splitnport
else:
    from urllib.parse import splitnport

DEFAULT_HTTP_HOST = "127.0.0.1"
DEFAULT_UNIX_SOCKET = "http+unix://var/run/docker.sock"
DEFAULT_NPIPE = 'npipe:////./pipe/docker_engine'

BYTE_UNITS = {
    'b': 1,
    'k': 1024,
    'm': 1024 * 1024,
    'g': 1024 * 1024 * 1024
}


def create_ipam_pool(subnet=None, iprange=None, gateway=None,
                     aux_addresses=None):
    return {
        'Subnet': subnet,
        'IPRange': iprange,
        'Gateway': gateway,
        'AuxiliaryAddresses': aux_addresses
    }


def create_ipam_config(driver='default', pool_configs=None):
    return {
        'Driver': driver,
        'Config': pool_configs or []
    }


def mkbuildcontext(dockerfile):
    f = tempfile.NamedTemporaryFile()
    t = tarfile.open(mode='w', fileobj=f)
    if isinstance(dockerfile, io.StringIO):
        dfinfo = tarfile.TarInfo('Dockerfile')
        if six.PY3:
            raise TypeError('Please use io.BytesIO to create in-memory '
                            'Dockerfiles with Python 3')
        else:
            dfinfo.size = len(dockerfile.getvalue())
            dockerfile.seek(0)
    elif isinstance(dockerfile, io.BytesIO):
        dfinfo = tarfile.TarInfo('Dockerfile')
        dfinfo.size = len(dockerfile.getvalue())
        dockerfile.seek(0)
    else:
        dfinfo = t.gettarinfo(fileobj=dockerfile, arcname='Dockerfile')
    t.addfile(dfinfo, dockerfile)
    t.close()
    f.seek(0)
    return f


def decode_json_header(header):
    data = base64.b64decode(header)
    if six.PY3:
        data = data.decode('utf-8')
    return json.loads(data)


def tar(path, exclude=None, dockerfile=None, fileobj=None, gzip=False):
    if not fileobj:
        fileobj = tempfile.NamedTemporaryFile()
    t = tarfile.open(mode='w:gz' if gzip else 'w', fileobj=fileobj)

    root = os.path.abspath(path)
    exclude = exclude or []

    for path in sorted(exclude_paths(root, exclude, dockerfile=dockerfile)):
        t.add(os.path.join(root, path), arcname=path, recursive=False)

    t.close()
    fileobj.seek(0)
    return fileobj


def exclude_paths(root, patterns, dockerfile=None):
    """
    Given a root directory path and a list of .dockerignore patterns, return
    an iterator of all paths (both regular files and directories) in the root
    directory that do *not* match any of the patterns.

    All paths returned are relative to the root.
    """
    if dockerfile is None:
        dockerfile = 'Dockerfile'

    exceptions = [p for p in patterns if p.startswith('!')]

    include_patterns = [p[1:] for p in exceptions]
    include_patterns += [dockerfile, '.dockerignore']

    exclude_patterns = list(set(patterns) - set(exceptions))

    paths = get_paths(root, exclude_patterns, include_patterns,
                      has_exceptions=len(exceptions) > 0)

    return set(paths).union(
        # If the Dockerfile is in a subdirectory that is excluded, get_paths
        # will not descend into it and the file will be skipped. This ensures
        # it doesn't happen.
        set([dockerfile])
        if os.path.exists(os.path.join(root, dockerfile)) else set()
    )


def should_include(path, exclude_patterns, include_patterns):
    """
    Given a path, a list of exclude patterns, and a list of inclusion patterns:

    1. Returns True if the path doesn't match any exclusion pattern
    2. Returns False if the path matches an exclusion pattern and doesn't match
       an inclusion pattern
    3. Returns true if the path matches an exclusion pattern and matches an
       inclusion pattern
    """
    for pattern in exclude_patterns:
        if match_path(path, pattern):
            for pattern in include_patterns:
                if match_path(path, pattern):
                    return True
            return False
    return True


def get_paths(root, exclude_patterns, include_patterns, has_exceptions=False):
    paths = []

    for parent, dirs, files in os.walk(root, topdown=True, followlinks=False):
        parent = os.path.relpath(parent, root)
        if parent == '.':
            parent = ''

        # If exception rules exist, we can't skip recursing into ignored
        # directories, as we need to look for exceptions in them.
        #
        # It may be possible to optimize this further for exception patterns
        # that *couldn't* match within ignored directores.
        #
        # This matches the current docker logic (as of 2015-11-24):
        # https://github.com/docker/docker/blob/37ba67bf636b34dc5c0c0265d62a089d0492088f/pkg/archive/archive.go#L555-L557

        if not has_exceptions:

            # Remove excluded patterns from the list of directories to traverse
            # by mutating the dirs we're iterating over.
            # This looks strange, but is considered the correct way to skip
            # traversal. See https://docs.python.org/2/library/os.html#os.walk

            dirs[:] = [d for d in dirs if
                       should_include(os.path.join(parent, d),
                                      exclude_patterns, include_patterns)]

        for path in dirs:
            if should_include(os.path.join(parent, path),
                              exclude_patterns, include_patterns):
                paths.append(os.path.join(parent, path))

        for path in files:
            if should_include(os.path.join(parent, path),
                              exclude_patterns, include_patterns):
                paths.append(os.path.join(parent, path))

    return paths


def match_path(path, pattern):
    pattern = pattern.rstrip('/')
    if pattern:
        pattern = os.path.relpath(pattern)

    pattern_components = pattern.split(os.path.sep)
    path_components = path.split(os.path.sep)[:len(pattern_components)]
    return fnmatch('/'.join(path_components), pattern)


def compare_version(v1, v2):
    """Compare docker versions

    >>> v1 = '1.9'
    >>> v2 = '1.10'
    >>> compare_version(v1, v2)
    1
    >>> compare_version(v2, v1)
    -1
    >>> compare_version(v2, v2)
    0
    """
    s1 = StrictVersion(v1)
    s2 = StrictVersion(v2)
    if s1 == s2:
        return 0
    elif s1 > s2:
        return -1
    else:
        return 1


def version_lt(v1, v2):
    return compare_version(v1, v2) > 0


def version_gte(v1, v2):
    return not version_lt(v1, v2)


def ping_registry(url):
    warnings.warn(
        'The `ping_registry` method is deprecated and will be removed.',
        DeprecationWarning
    )

    return ping(url + '/v2/', [401]) or ping(url + '/v1/_ping')


def ping(url, valid_4xx_statuses=None):
    try:
        res = requests.get(url, timeout=3)
    except Exception:
        return False
    else:
        # We don't send yet auth headers
        # and a v2 registry will respond with status 401
        return (
            res.status_code < 400 or
            (valid_4xx_statuses and res.status_code in valid_4xx_statuses)
        )


def _convert_port_binding(binding):
    result = {'HostIp': '', 'HostPort': ''}
    if isinstance(binding, tuple):
        if len(binding) == 2:
            result['HostPort'] = binding[1]
            result['HostIp'] = binding[0]
        elif isinstance(binding[0], six.string_types):
            result['HostIp'] = binding[0]
        else:
            result['HostPort'] = binding[0]
    elif isinstance(binding, dict):
        if 'HostPort' in binding:
            result['HostPort'] = binding['HostPort']
            if 'HostIp' in binding:
                result['HostIp'] = binding['HostIp']
        else:
            raise ValueError(binding)
    else:
        result['HostPort'] = binding

    if result['HostPort'] is None:
        result['HostPort'] = ''
    else:
        result['HostPort'] = str(result['HostPort'])

    return result


def convert_port_bindings(port_bindings):
    result = {}
    for k, v in six.iteritems(port_bindings):
        key = str(k)
        if '/' not in key:
            key += '/tcp'
        if isinstance(v, list):
            result[key] = [_convert_port_binding(binding) for binding in v]
        else:
            result[key] = [_convert_port_binding(v)]
    return result


def convert_volume_binds(binds):
    if isinstance(binds, list):
        return binds

    result = []
    for k, v in binds.items():
        if isinstance(k, six.binary_type):
            k = k.decode('utf-8')

        if isinstance(v, dict):
            if 'ro' in v and 'mode' in v:
                raise ValueError(
                    'Binding cannot contain both "ro" and "mode": {}'
                    .format(repr(v))
                )

            bind = v['bind']
            if isinstance(bind, six.binary_type):
                bind = bind.decode('utf-8')

            if 'ro' in v:
                mode = 'ro' if v['ro'] else 'rw'
            elif 'mode' in v:
                mode = v['mode']
            else:
                mode = 'rw'

            result.append(
                six.text_type('{0}:{1}:{2}').format(k, bind, mode)
            )
        else:
            if isinstance(v, six.binary_type):
                v = v.decode('utf-8')
            result.append(
                six.text_type('{0}:{1}:rw').format(k, v)
            )
    return result


def convert_tmpfs_mounts(tmpfs):
    if isinstance(tmpfs, dict):
        return tmpfs

    if not isinstance(tmpfs, list):
        raise ValueError(
            'Expected tmpfs value to be either a list or a dict, found: {}'
            .format(type(tmpfs).__name__)
        )

    result = {}
    for mount in tmpfs:
        if isinstance(mount, six.string_types):
            if ":" in mount:
                name, options = mount.split(":", 1)
            else:
                name = mount
                options = ""

        else:
            raise ValueError(
                "Expected item in tmpfs list to be a string, found: {}"
                .format(type(mount).__name__)
            )

        result[name] = options
    return result


def parse_repository_tag(repo_name):
    parts = repo_name.rsplit('@', 1)
    if len(parts) == 2:
        return tuple(parts)
    parts = repo_name.rsplit(':', 1)
    if len(parts) == 2 and '/' not in parts[1]:
        return tuple(parts)
    return repo_name, None


# Based on utils.go:ParseHost http://tinyurl.com/nkahcfh
# fd:// protocol unsupported (for obvious reasons)
# Added support for http and https
# Protocol translation: tcp -> http, unix -> http+unix
def parse_host(addr, is_win32=False, tls=False):
    proto = "http+unix"
    port = None
    path = ''

    if not addr and is_win32:
        addr = DEFAULT_NPIPE

    if not addr or addr.strip() == 'unix://':
        return DEFAULT_UNIX_SOCKET

    addr = addr.strip()
    if addr.startswith('http://'):
        addr = addr.replace('http://', 'tcp://')
    if addr.startswith('http+unix://'):
        addr = addr.replace('http+unix://', 'unix://')

    if addr == 'tcp://':
        raise errors.DockerException(
            "Invalid bind address format: {0}".format(addr)
        )
    elif addr.startswith('unix://'):
        addr = addr[7:]
    elif addr.startswith('tcp://'):
        proto = 'http{0}'.format('s' if tls else '')
        addr = addr[6:]
    elif addr.startswith('https://'):
        proto = "https"
        addr = addr[8:]
    elif addr.startswith('npipe://'):
        proto = 'npipe'
        addr = addr[8:]
    elif addr.startswith('fd://'):
        raise errors.DockerException("fd protocol is not implemented")
    else:
        if "://" in addr:
            raise errors.DockerException(
                "Invalid bind address protocol: {0}".format(addr)
            )
        proto = "https" if tls else "http"

    if proto in ("http", "https"):
        address_parts = addr.split('/', 1)
        host = address_parts[0]
        if len(address_parts) == 2:
            path = '/' + address_parts[1]
        host, port = splitnport(host)

        if port is None:
            raise errors.DockerException(
                "Invalid port: {0}".format(addr)
            )

        if not host:
            host = DEFAULT_HTTP_HOST
    else:
        host = addr

    if proto in ("http", "https") and port == -1:
        raise errors.DockerException(
            "Bind address needs a port: {0}".format(addr))

    if proto == "http+unix" or proto == 'npipe':
        return "{0}://{1}".format(proto, host).rstrip('/')
    return "{0}://{1}:{2}{3}".format(proto, host, port, path).rstrip('/')


def parse_devices(devices):
    device_list = []
    for device in devices:
        if isinstance(device, dict):
            device_list.append(device)
            continue
        if not isinstance(device, six.string_types):
            raise errors.DockerException(
                'Invalid device type {0}'.format(type(device))
            )
        device_mapping = device.split(':')
        if device_mapping:
            path_on_host = device_mapping[0]
            if len(device_mapping) > 1:
                path_in_container = device_mapping[1]
            else:
                path_in_container = path_on_host
            if len(device_mapping) > 2:
                permissions = device_mapping[2]
            else:
                permissions = 'rwm'
            device_list.append({
                'PathOnHost': path_on_host,
                'PathInContainer': path_in_container,
                'CgroupPermissions': permissions
            })
    return device_list


def kwargs_from_env(ssl_version=None, assert_hostname=None, environment=None):
    if not environment:
        environment = os.environ
    host = environment.get('DOCKER_HOST')

    # empty string for cert path is the same as unset.
    cert_path = environment.get('DOCKER_CERT_PATH') or None

    # empty string for tls verify counts as "false".
    # Any value or 'unset' counts as true.
    tls_verify = environment.get('DOCKER_TLS_VERIFY')
    if tls_verify == '':
        tls_verify = False
    else:
        tls_verify = tls_verify is not None
    enable_tls = cert_path or tls_verify

    params = {}

    if host:
        params['base_url'] = (
            host.replace('tcp://', 'https://') if enable_tls else host
        )

    if not enable_tls:
        return params

    if not cert_path:
        cert_path = os.path.join(os.path.expanduser('~'), '.docker')

    if not tls_verify and assert_hostname is None:
        # assert_hostname is a subset of TLS verification,
        # so if it's not set already then set it to false.
        assert_hostname = False

    params['tls'] = tls.TLSConfig(
        client_cert=(os.path.join(cert_path, 'cert.pem'),
                     os.path.join(cert_path, 'key.pem')),
        ca_cert=os.path.join(cert_path, 'ca.pem'),
        verify=tls_verify,
        ssl_version=ssl_version,
        assert_hostname=assert_hostname,
    )

    return params


def convert_filters(filters):
    result = {}
    for k, v in six.iteritems(filters):
        if isinstance(v, bool):
            v = 'true' if v else 'false'
        if not isinstance(v, list):
            v = [v, ]
        result[k] = v
    return json.dumps(result)


def datetime_to_timestamp(dt):
    """Convert a UTC datetime to a Unix timestamp"""
    delta = dt - datetime.utcfromtimestamp(0)
    return delta.seconds + delta.days * 24 * 3600


def parse_bytes(s):
    if isinstance(s, six.integer_types + (float,)):
        return s
    if len(s) == 0:
        return 0

    if s[-2:-1].isalpha() and s[-1].isalpha():
        if s[-1] == "b" or s[-1] == "B":
            s = s[:-1]
    units = BYTE_UNITS
    suffix = s[-1].lower()

    # Check if the variable is a string representation of an int
    # without a units part. Assuming that the units are bytes.
    if suffix.isdigit():
        digits_part = s
        suffix = 'b'
    else:
        digits_part = s[:-1]

    if suffix in units.keys() or suffix.isdigit():
        try:
            digits = int(digits_part)
        except ValueError:
            raise errors.DockerException(
                'Failed converting the string value for memory ({0}) to'
                ' an integer.'.format(digits_part)
            )

        # Reconvert to long for the final result
        s = int(digits * units[suffix])
    else:
        raise errors.DockerException(
            'The specified value for memory ({0}) should specify the'
            ' units. The postfix should be one of the `b` `k` `m` `g`'
            ' characters'.format(s)
        )

    return s


def host_config_type_error(param, param_value, expected):
    error_msg = 'Invalid type for {0} param: expected {1} but found {2}'
    return TypeError(error_msg.format(param, expected, type(param_value)))


def host_config_version_error(param, version, less_than=True):
    operator = '<' if less_than else '>'
    error_msg = '{0} param is not supported in API versions {1} {2}'
    return errors.InvalidVersion(error_msg.format(param, operator, version))


def host_config_value_error(param, param_value):
    error_msg = 'Invalid value for {0} param: {1}'
    return ValueError(error_msg.format(param, param_value))


def create_host_config(binds=None, port_bindings=None, lxc_conf=None,
                       publish_all_ports=False, links=None, privileged=False,
                       dns=None, dns_search=None, volumes_from=None,
                       network_mode=None, restart_policy=None, cap_add=None,
                       cap_drop=None, devices=None, extra_hosts=None,
                       read_only=None, pid_mode=None, ipc_mode=None,
                       security_opt=None, ulimits=None, log_config=None,
                       mem_limit=None, memswap_limit=None,
                       mem_reservation=None, kernel_memory=None,
                       mem_swappiness=None, cgroup_parent=None,
                       group_add=None, cpu_quota=None,
                       cpu_period=None, blkio_weight=None,
                       blkio_weight_device=None, device_read_bps=None,
                       device_write_bps=None, device_read_iops=None,
                       device_write_iops=None, oom_kill_disable=False,
                       shm_size=None, sysctls=None, version=None, tmpfs=None,
                       oom_score_adj=None, dns_opt=None, cpu_shares=None,
                       cpuset_cpus=None, userns_mode=None, pids_limit=None):

    host_config = {}

    if not version:
        warnings.warn(
            'docker.utils.create_host_config() is deprecated. Please use '
            'Client.create_host_config() instead.'
        )
        version = constants.DEFAULT_DOCKER_API_VERSION

    if mem_limit is not None:
        host_config['Memory'] = parse_bytes(mem_limit)

    if memswap_limit is not None:
        host_config['MemorySwap'] = parse_bytes(memswap_limit)

    if mem_reservation:
        if version_lt(version, '1.21'):
            raise host_config_version_error('mem_reservation', '1.21')

        host_config['MemoryReservation'] = parse_bytes(mem_reservation)

    if kernel_memory:
        if version_lt(version, '1.21'):
            raise host_config_version_error('kernel_memory', '1.21')

        host_config['KernelMemory'] = parse_bytes(kernel_memory)

    if mem_swappiness is not None:
        if version_lt(version, '1.20'):
            raise host_config_version_error('mem_swappiness', '1.20')
        if not isinstance(mem_swappiness, int):
            raise host_config_type_error(
                'mem_swappiness', mem_swappiness, 'int'
            )

        host_config['MemorySwappiness'] = mem_swappiness

    if shm_size is not None:
        if isinstance(shm_size, six.string_types):
            shm_size = parse_bytes(shm_size)

        host_config['ShmSize'] = shm_size

    if pid_mode not in (None, 'host'):
        raise host_config_value_error('pid_mode', pid_mode)
    elif pid_mode:
        host_config['PidMode'] = pid_mode

    if ipc_mode:
        host_config['IpcMode'] = ipc_mode

    if privileged:
        host_config['Privileged'] = privileged

    if oom_kill_disable:
        if version_lt(version, '1.20'):
            raise host_config_version_error('oom_kill_disable', '1.19')

        host_config['OomKillDisable'] = oom_kill_disable

    if oom_score_adj:
        if version_lt(version, '1.22'):
            raise host_config_version_error('oom_score_adj', '1.22')
        if not isinstance(oom_score_adj, int):
            raise host_config_type_error(
                'oom_score_adj', oom_score_adj, 'int'
            )
        host_config['OomScoreAdj'] = oom_score_adj

    if publish_all_ports:
        host_config['PublishAllPorts'] = publish_all_ports

    if read_only is not None:
        host_config['ReadonlyRootfs'] = read_only

    if dns_search:
        host_config['DnsSearch'] = dns_search

    if network_mode:
        host_config['NetworkMode'] = network_mode
    elif network_mode is None and compare_version('1.19', version) > 0:
        host_config['NetworkMode'] = 'default'

    if restart_policy:
        if not isinstance(restart_policy, dict):
            raise host_config_type_error(
                'restart_policy', restart_policy, 'dict'
            )

        host_config['RestartPolicy'] = restart_policy

    if cap_add:
        host_config['CapAdd'] = cap_add

    if cap_drop:
        host_config['CapDrop'] = cap_drop

    if devices:
        host_config['Devices'] = parse_devices(devices)

    if group_add:
        if version_lt(version, '1.20'):
            raise host_config_version_error('group_add', '1.20')

        host_config['GroupAdd'] = [six.text_type(grp) for grp in group_add]

    if dns is not None:
        host_config['Dns'] = dns

    if dns_opt is not None:
        if version_lt(version, '1.21'):
            raise host_config_version_error('dns_opt', '1.21')

        host_config['DnsOptions'] = dns_opt

    if security_opt is not None:
        if not isinstance(security_opt, list):
            raise host_config_type_error('security_opt', security_opt, 'list')

        host_config['SecurityOpt'] = security_opt

    if sysctls:
        if not isinstance(sysctls, dict):
            raise host_config_type_error('sysctls', sysctls, 'dict')
        host_config['Sysctls'] = {}
        for k, v in six.iteritems(sysctls):
            host_config['Sysctls'][k] = six.text_type(v)

    if volumes_from is not None:
        if isinstance(volumes_from, six.string_types):
            volumes_from = volumes_from.split(',')

        host_config['VolumesFrom'] = volumes_from

    if binds is not None:
        host_config['Binds'] = convert_volume_binds(binds)

    if port_bindings is not None:
        host_config['PortBindings'] = convert_port_bindings(port_bindings)

    if extra_hosts is not None:
        if isinstance(extra_hosts, dict):
            extra_hosts = [
                '{0}:{1}'.format(k, v)
                for k, v in sorted(six.iteritems(extra_hosts))
            ]

        host_config['ExtraHosts'] = extra_hosts

    if links is not None:
        host_config['Links'] = normalize_links(links)

    if isinstance(lxc_conf, dict):
        formatted = []
        for k, v in six.iteritems(lxc_conf):
            formatted.append({'Key': k, 'Value': str(v)})
        lxc_conf = formatted

    if lxc_conf is not None:
        host_config['LxcConf'] = lxc_conf

    if cgroup_parent is not None:
        host_config['CgroupParent'] = cgroup_parent

    if ulimits is not None:
        if not isinstance(ulimits, list):
            raise host_config_type_error('ulimits', ulimits, 'list')
        host_config['Ulimits'] = []
        for l in ulimits:
            if not isinstance(l, Ulimit):
                l = Ulimit(**l)
            host_config['Ulimits'].append(l)

    if log_config is not None:
        if not isinstance(log_config, LogConfig):
            if not isinstance(log_config, dict):
                raise host_config_type_error(
                    'log_config', log_config, 'LogConfig'
                )
            log_config = LogConfig(**log_config)

        host_config['LogConfig'] = log_config

    if cpu_quota:
        if not isinstance(cpu_quota, int):
            raise host_config_type_error('cpu_quota', cpu_quota, 'int')
        if version_lt(version, '1.19'):
            raise host_config_version_error('cpu_quota', '1.19')

        host_config['CpuQuota'] = cpu_quota

    if cpu_period:
        if not isinstance(cpu_period, int):
            raise host_config_type_error('cpu_period', cpu_period, 'int')
        if version_lt(version, '1.19'):
            raise host_config_version_error('cpu_period', '1.19')

        host_config['CpuPeriod'] = cpu_period

    if cpu_shares:
        if version_lt(version, '1.18'):
            raise host_config_version_error('cpu_shares', '1.18')

        if not isinstance(cpu_shares, int):
            raise host_config_type_error('cpu_shares', cpu_shares, 'int')

        host_config['CpuShares'] = cpu_shares

    if cpuset_cpus:
        if version_lt(version, '1.18'):
            raise host_config_version_error('cpuset_cpus', '1.18')

        host_config['CpuSetCpus'] = cpuset_cpus

    if blkio_weight:
        if not isinstance(blkio_weight, int):
            raise host_config_type_error('blkio_weight', blkio_weight, 'int')
        if version_lt(version, '1.22'):
            raise host_config_version_error('blkio_weight', '1.22')
        host_config["BlkioWeight"] = blkio_weight

    if blkio_weight_device:
        if not isinstance(blkio_weight_device, list):
            raise host_config_type_error(
                'blkio_weight_device', blkio_weight_device, 'list'
            )
        if version_lt(version, '1.22'):
            raise host_config_version_error('blkio_weight_device', '1.22')
        host_config["BlkioWeightDevice"] = blkio_weight_device

    if device_read_bps:
        if not isinstance(device_read_bps, list):
            raise host_config_type_error(
                'device_read_bps', device_read_bps, 'list'
            )
        if version_lt(version, '1.22'):
            raise host_config_version_error('device_read_bps', '1.22')
        host_config["BlkioDeviceReadBps"] = device_read_bps

    if device_write_bps:
        if not isinstance(device_write_bps, list):
            raise host_config_type_error(
                'device_write_bps', device_write_bps, 'list'
            )
        if version_lt(version, '1.22'):
            raise host_config_version_error('device_write_bps', '1.22')
        host_config["BlkioDeviceWriteBps"] = device_write_bps

    if device_read_iops:
        if not isinstance(device_read_iops, list):
            raise host_config_type_error(
                'device_read_iops', device_read_iops, 'list'
            )
        if version_lt(version, '1.22'):
            raise host_config_version_error('device_read_iops', '1.22')
        host_config["BlkioDeviceReadIOps"] = device_read_iops

    if device_write_iops:
        if not isinstance(device_write_iops, list):
            raise host_config_type_error(
                'device_write_iops', device_write_iops, 'list'
            )
        if version_lt(version, '1.22'):
            raise host_config_version_error('device_write_iops', '1.22')
        host_config["BlkioDeviceWriteIOps"] = device_write_iops

    if tmpfs:
        if version_lt(version, '1.22'):
            raise host_config_version_error('tmpfs', '1.22')
        host_config["Tmpfs"] = convert_tmpfs_mounts(tmpfs)

    if userns_mode:
        if version_lt(version, '1.23'):
            raise host_config_version_error('userns_mode', '1.23')

        if userns_mode != "host":
            raise host_config_value_error("userns_mode", userns_mode)
        host_config['UsernsMode'] = userns_mode

    if pids_limit:
        if not isinstance(pids_limit, int):
            raise host_config_type_error('pids_limit', pids_limit, 'int')
        if version_lt(version, '1.23'):
            raise host_config_version_error('pids_limit', '1.23')
        host_config["PidsLimit"] = pids_limit

    return host_config


def normalize_links(links):
    if isinstance(links, dict):
        links = six.iteritems(links)

    return ['{0}:{1}'.format(k, v) for k, v in sorted(links)]


def create_networking_config(endpoints_config=None):
    networking_config = {}

    if endpoints_config:
        networking_config["EndpointsConfig"] = endpoints_config

    return networking_config


def create_endpoint_config(version, aliases=None, links=None,
                           ipv4_address=None, ipv6_address=None,
                           link_local_ips=None):
    if version_lt(version, '1.22'):
        raise errors.InvalidVersion(
            'Endpoint config is not supported for API version < 1.22'
        )
    endpoint_config = {}

    if aliases:
        endpoint_config["Aliases"] = aliases

    if links:
        endpoint_config["Links"] = normalize_links(links)

    ipam_config = {}
    if ipv4_address:
        ipam_config['IPv4Address'] = ipv4_address

    if ipv6_address:
        ipam_config['IPv6Address'] = ipv6_address

    if link_local_ips is not None:
        if version_lt(version, '1.24'):
            raise errors.InvalidVersion(
                'link_local_ips is not supported for API version < 1.24'
            )
        ipam_config['LinkLocalIPs'] = link_local_ips

    if ipam_config:
        endpoint_config['IPAMConfig'] = ipam_config

    return endpoint_config


def parse_env_file(env_file):
    """
    Reads a line-separated environment file.
    The format of each line should be "key=value".
    """
    environment = {}

    with open(env_file, 'r') as f:
        for line in f:

            if line[0] == '#':
                continue

            parse_line = line.strip().split('=', 1)
            if len(parse_line) == 2:
                k, v = parse_line
                environment[k] = v
            else:
                raise errors.DockerException(
                    'Invalid line in environment file {0}:\n{1}'.format(
                        env_file, line))

    return environment


def split_command(command):
    if six.PY2 and not isinstance(command, six.binary_type):
        command = command.encode('utf-8')
    return shlex.split(command)


def format_environment(environment):
    def format_env(key, value):
        if value is None:
            return key
        if isinstance(value, six.binary_type):
            value = value.decode('utf-8')

        return u'{key}={value}'.format(key=key, value=value)
    return [format_env(*var) for var in six.iteritems(environment)]


def create_container_config(
    version, image, command, hostname=None, user=None, detach=False,
    stdin_open=False, tty=False, mem_limit=None, ports=None, environment=None,
    dns=None, volumes=None, volumes_from=None, network_disabled=False,
    entrypoint=None, cpu_shares=None, working_dir=None, domainname=None,
    memswap_limit=None, cpuset=None, host_config=None, mac_address=None,
    labels=None, volume_driver=None, stop_signal=None, networking_config=None,
):
    if isinstance(command, six.string_types):
        command = split_command(command)

    if isinstance(entrypoint, six.string_types):
        entrypoint = split_command(entrypoint)

    if isinstance(environment, dict):
        environment = format_environment(environment)

    if labels is not None and compare_version('1.18', version) < 0:
        raise errors.InvalidVersion(
            'labels were only introduced in API version 1.18'
        )

    if cpuset is not None or cpu_shares is not None:
        if version_gte(version, '1.18'):
            warnings.warn(
                'The cpuset_cpus and cpu_shares options have been moved to '
                'host_config in API version 1.18, and will be removed',
                DeprecationWarning
            )

    if stop_signal is not None and compare_version('1.21', version) < 0:
        raise errors.InvalidVersion(
            'stop_signal was only introduced in API version 1.21'
        )

    if compare_version('1.19', version) < 0:
        if volume_driver is not None:
            raise errors.InvalidVersion(
                'Volume drivers were only introduced in API version 1.19'
            )
        mem_limit = mem_limit if mem_limit is not None else 0
        memswap_limit = memswap_limit if memswap_limit is not None else 0
    else:
        if mem_limit is not None:
            raise errors.InvalidVersion(
                'mem_limit has been moved to host_config in API version 1.19'
            )

        if memswap_limit is not None:
            raise errors.InvalidVersion(
                'memswap_limit has been moved to host_config in API '
                'version 1.19'
            )

    if isinstance(labels, list):
        labels = dict((lbl, six.text_type('')) for lbl in labels)

    if mem_limit is not None:
        mem_limit = parse_bytes(mem_limit)

    if memswap_limit is not None:
        memswap_limit = parse_bytes(memswap_limit)

    if isinstance(ports, list):
        exposed_ports = {}
        for port_definition in ports:
            port = port_definition
            proto = 'tcp'
            if isinstance(port_definition, tuple):
                if len(port_definition) == 2:
                    proto = port_definition[1]
                port = port_definition[0]
            exposed_ports['{0}/{1}'.format(port, proto)] = {}
        ports = exposed_ports

    if isinstance(volumes, six.string_types):
        volumes = [volumes, ]

    if isinstance(volumes, list):
        volumes_dict = {}
        for vol in volumes:
            volumes_dict[vol] = {}
        volumes = volumes_dict

    if volumes_from:
        if not isinstance(volumes_from, six.string_types):
            volumes_from = ','.join(volumes_from)
    else:
        # Force None, an empty list or dict causes client.start to fail
        volumes_from = None

    attach_stdin = False
    attach_stdout = False
    attach_stderr = False
    stdin_once = False

    if not detach:
        attach_stdout = True
        attach_stderr = True

        if stdin_open:
            attach_stdin = True
            stdin_once = True

    if compare_version('1.10', version) >= 0:
        message = ('{0!r} parameter has no effect on create_container().'
                   ' It has been moved to host_config')
        if dns is not None:
            raise errors.InvalidVersion(message.format('dns'))
        if volumes_from is not None:
            raise errors.InvalidVersion(message.format('volumes_from'))

    return {
        'Hostname': hostname,
        'Domainname': domainname,
        'ExposedPorts': ports,
        'User': six.text_type(user) if user else None,
        'Tty': tty,
        'OpenStdin': stdin_open,
        'StdinOnce': stdin_once,
        'Memory': mem_limit,
        'AttachStdin': attach_stdin,
        'AttachStdout': attach_stdout,
        'AttachStderr': attach_stderr,
        'Env': environment,
        'Cmd': command,
        'Dns': dns,
        'Image': image,
        'Volumes': volumes,
        'VolumesFrom': volumes_from,
        'NetworkDisabled': network_disabled,
        'Entrypoint': entrypoint,
        'CpuShares': cpu_shares,
        'Cpuset': cpuset,
        'CpusetCpus': cpuset,
        'WorkingDir': working_dir,
        'MemorySwap': memswap_limit,
        'HostConfig': host_config,
        'NetworkingConfig': networking_config,
        'MacAddress': mac_address,
        'Labels': labels,
        'VolumeDriver': volume_driver,
        'StopSignal': stop_signal
    }
