# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from docker import DockerClient
from docker.errors import DockerException, NotFound, APIError, ContainerError, ImageNotFound
import time

'''
'''
def get_docker_client():
    try:
        return DockerClient(base_url='unix:/%s' % settings.DOCKER_SOCK_DIR)
    except DockerException:
        return None

'''
'''
def get_all_images():
    client = get_docker_client()

    images = []

    if not client:
        return images

    for image in client.images.list():
        images.append({
            'id': image.id,
            'short_id': image.short_id,
            'tags': image.tags
        })

    return images

'''
'''
def get_all_containers():
    client = get_docker_client()

    containers = []

    if not client:
        return containers

    for container in client.containers.list(all=True):
        if container.name in settings.DOCKER_FILTERS:
            continue

        containers.append({
            'id': container.id,
            'short_id': container.short_id,
            'name': container.name,
            'image': container.image,
            'labels': container.labels,
            'status': container.status,
            'attrs': container.attrs
        })
        
    return containers

'''
'''
def get_all_external_ports():
    ports = []

    for m in map(lambda x: x.get('attrs').get('NetworkSettings').get('Ports'), get_all_containers()):
        if not m:
            continue

        for _, v in m.iteritems():
            if not v:
                continue
            
            port = map(lambda x: x['HostPort'], v)
            ports.extend(port)

    return ports

'''
'''
def get_network(name=None):
    if not name:
        return None

    client = get_docker_client()

    if not client:
        return None

    try:
        network = client.networks.get(name)

        return {
            'id': network.id,
            'short_id': network.short_id,
            'name': network.name,
            'attrs': network.attrs
        }
    except (NotFound, APIError):
        return None

'''
'''
def get_internal_ip(container_name_or_id=None):
    # check name
    if not container_name_or_id:
        return None

    # check client
    client = get_docker_client()
    if not client:
        return None

    # check network
    network = get_network(settings.INTERNAL_NETWORK_NAME)
    if not network:
        return None

    try:
        container = client.containers.get(container_name_or_id)
        internal_ip = container.attrs.get('NetworkSettings').get('Networks').get(network.get('name')).get('IPAddress')
        
        return str(internal_ip)
    except (NotFound, APIError):
        return None

'''
'''
def run_container(image=None, name=None, ports=[], volumes=None, net=None, memory_limit=None, memory_swap_limit=None):
    if not name:
        return False

    client = get_docker_client()

    if not client:
        return False

    try:
        client.containers.run(
            image, 
            None, 
            name=name, 
            detach=True, 
            ports=ports, 
            volumes=volumes, 
            network=net, 
            mem_limit=memory_limit, 
            memswap_limit=memory_swap_limit
        )
        return True
    except (ContainerError, ImageNotFound, APIError):
        return False

'''
'''
def start_container(id_or_name=None):
    if not id:
        return None

    client = get_docker_client()

    if not client:
        return None

    try:
        container = client.containers.get(id_or_name)
        container.start()

        time.sleep(1)

        container.reload()

        return {
            'id': container.id,
            'short_id': container.short_id,
            'name': container.name,
            'image': container.image,
            'labels': container.labels,
            'status': container.status
        }
    except (NotFound, APIError):
        return None

'''
'''
def restart_container(id_or_name=None):
    if not id:
        return None

    client = get_docker_client()

    if not client:
        return None

    try:
        container = client.containers.get(id)
        container.restart()

        time.sleep(1)

        container.reload()

        return {
            'id': container.id,
            'short_id': container.short_id,
            'name': container.name,
            'image': container.image,
            'labels': container.labels,
            'status': container.status
        }
    except (NotFound, APIError):
        return None

'''
'''
def stop_container(id=None):
    if not id:
        return None

    client = get_docker_client()

    if not client:
        return None

    try:
        container = client.containers.get(id)
        container.stop()

        time.sleep(1)

        container.reload()

        return {
            'id': container.id,
            'short_id': container.short_id,
            'name': container.name,
            'image': container.image,
            'labels': container.labels,
            'status': container.status
        }
    except (NotFound, APIError):
        return None

'''
'''
def execute_command(container_id_or_name=None, command=None):
    if not container_id_or_name or not command:
        return None

    client = get_docker_client()

    if not client:
        return None

    try:
        container = client.containers.get(container_id_or_name)
        (exit_code, unused_output) = container.exec_run(command)
        return (False, True)[exit_code == 0]
    except (NotFound, APIError):
        return None

'''
'''
def copy_in(container_id_or_name=None, path=None, tarfile=None):
    if not container_id_or_name or not path or not tarfile:
        return False

    client = get_docker_client()

    if not client:
        return False

    try:
        file = open(tarfile, 'r')
        container = client.containers.get(container_id_or_name)
        result = container.put_archive(path, file)
        file.close()
        return result
    except (NotFound, APIError, IOError):
        return False

'''
'''
def container_is_running(id_or_name=None):
    if not id_or_name:
        return False

    client = get_docker_client()

    if not client:
        return False

    try:
        container = client.containers.get(id_or_name)
        return (False, True)[container.status == 'running']
    except (NotFound, APIError):
        return False
