# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import base64
import datetime
import shlex
import re
import os

try:
    import simplejson as json
except Exception:
    import json

from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import b

from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.base import KeyCertificateConnection
from libcloud.common.types import InvalidCredsError

from libcloud.container.base import (Container, ContainerDriver,
                                     ContainerImage)

from libcloud.container.providers import Provider
from libcloud.container.types import ContainerState


VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
                        httplib.NO_CONTENT]


class DockerResponse(JsonResponse):

    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
                            httplib.NO_CONTENT]

    def parse_body(self):
        if len(self.body) == 0 and not self.parse_zero_length_body:
            return self.body

        try:
            # error responses are tricky in Docker. Eg response could be
            # an error, but response status could still be 200
            content_type = self.headers.get('content-type', 'application/json')
            if content_type == 'application/json' or content_type == '':
                if self.headers.get('transfer-encoding') == 'chunked' and \
                        'fromImage' in self.request.url:
                    body = [json.loads(chunk) for chunk in
                            self.body.strip().replace('\r', '').split('\n')]
                else:
                    body = json.loads(self.body)
            else:
                body = self.body
        except ValueError:
            m = re.search('Error: (.+?)"', self.body)
            if m:
                error_msg = m.group(1)
                raise Exception(error_msg)
            else:
                raise Exception(
                    'ConnectionError: Failed to parse JSON response')
        return body

    def parse_error(self):
        if self.status == 401:
            raise InvalidCredsError('Invalid credentials')
        return self.body

    def success(self):
        return self.status in self.valid_response_codes


class DockerException(Exception):

    def __init__(self, code, message):
        self.code = code
        self.message = message
        self.args = (code, message)

    def __str__(self):
        return "%s %s" % (self.code, self.message)

    def __repr__(self):
        return "DockerException %s %s" % (self.code, self.message)


class DockerConnection(ConnectionUserAndKey):

    responseCls = DockerResponse
    timeout = 60

    def add_default_headers(self, headers):
        """
        Add parameters that are necessary for every request
        If user and password are specified, include a base http auth
        header
        """
        headers['Content-Type'] = 'application/json'
        if self.user_id and self.key:
            user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
            headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
        return headers


class DockertlsConnection(KeyCertificateConnection):

    responseCls = DockerResponse

    def __init__(self, key, secret, secure=True,
                 host='localhost',
                 port=4243, key_file='', cert_file='', **kwargs):

        super(DockertlsConnection, self).__init__(key_file=key_file,
                                                  cert_file=cert_file,
                                                  secure=secure, host=host,
                                                  port=port, url=None,
                                                  proxy_url=None,
                                                  timeout=None, backoff=None,
                                                  retry_delay=None)
        if key_file:
            keypath = os.path.expanduser(key_file)
            is_file_path = os.path.exists(keypath) and os.path.isfile(keypath)
            if not is_file_path:
                raise InvalidCredsError(
                    'You need an key PEM file to authenticate with '
                    'Docker tls. This can be found in the server.'
                )
            self.key_file = key_file

            certpath = os.path.expanduser(cert_file)
            is_file_path = os.path.exists(
                certpath) and os.path.isfile(certpath)
            if not is_file_path:
                raise InvalidCredsError(
                    'You need an certificate PEM file to authenticate with '
                    'Docker tls. This can be found in the server.'
                )
            self.cert_file = cert_file

    def add_default_headers(self, headers):

        headers['Content-Type'] = 'application/json'
        return headers


class DockerContainerDriver(ContainerDriver):
    """
    Docker container driver class.

    >>> from libcloud.container.providers import get_driver
    >>> driver = get_driver('docker')
    >>> conn = driver(host='198.61.239.128', port=4243)
    >>> conn.list_containers()
    or connecting to http basic auth protected https host:
    >>> conn = driver('user', 'pass', host='https://198.61.239.128', port=443)

    connect with tls authentication, by providing a hostname, port, a private
    key file (.pem) and certificate (.pem) file
    >>> conn = driver(host='https://198.61.239.128',
    >>> port=4243, key_file='key.pem', cert_file='cert.pem')
    """

    type = Provider.DOCKER
    name = 'Docker'
    website = 'http://docker.io'
    connectionCls = DockerConnection
    supports_clusters = False
    version = '1.24'

    def __init__(self, key='', secret='', secure=False, host='localhost',
                 port=4243, key_file=None, cert_file=None):
        """
        :param    key: API key or username to used (required)
        :type     key: ``str``

        :param    secret: Secret password to be used (required)
        :type     secret: ``str``

        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
                only support HTTPS, and it is on by default.
        :type     secure: ``bool``

        :param    host: Override hostname used for connections.
        :type     host: ``str``

        :param    port: Override port used for connections.
        :type     port: ``int``

        :param    key_file: Path to private key for TLS connection (optional)
        :type     key_file: ``str``

        :param    cert_file: Path to public key for TLS connection (optional)
        :type     cert_file: ``str``

        :return: ``None``
        """
        if key_file:
            self.connectionCls = DockertlsConnection
            self.key_file = key_file
            self.cert_file = cert_file
            secure = True

        if host.startswith('https://'):
            secure = True

        # strip the prefix
        prefixes = ['http://', 'https://']
        for prefix in prefixes:
            if host.startswith(prefix):
                host = host.strip(prefix)

        super(DockerContainerDriver, self).__init__(key=key, secret=secret,
                                                    secure=secure, host=host,
                                                    port=port,
                                                    key_file=key_file,
                                                    cert_file=cert_file)

        if key_file or cert_file:
            # docker tls authentication-
            # https://docs.docker.com/articles/https/
            # We pass two files, a key_file with the
            # private key and cert_file with the certificate
            # libcloud will handle them through LibcloudHTTPSConnection
            if not (key_file and cert_file):
                raise Exception(
                    'Needs both private key file and '
                    'certificate file for tls authentication')

        self.connection.secure = secure
        self.connection.host = host
        self.connection.port = port
        # set API version
        self.version = self._get_api_version()

    def _ex_connection_class_kwargs(self):
        kwargs = {}
        if hasattr(self, 'key_file'):
            kwargs['key_file'] = self.key_file
        if hasattr(self, 'cert_file'):
            kwargs['cert_file'] = self.cert_file
        return kwargs

    def install_image(self, path):
        """
        Install a container image from a remote path.

        :param path: Path to the container image
        :type  path: ``str``

        :rtype: :class:`libcloud.container.base.ContainerImage`
        """
        payload = {
        }
        data = json.dumps(payload)

        result = self.connection.request('/v%s/images/create?fromImage=%s' %
                                         (self.version, path), data=data,
                                         method='POST')
        if "errorDetail" in result.body:
            raise DockerException(None, result.body)
        image_id = None

        # the response is slightly different if the image is already present
        # and it's not downloaded. both messages below indicate that the image
        # is available for use to the daemon
        if re.search(r'Downloaded newer image', result.body) or \
                re.search(r'"Status: Image is up to date', result.body):
            if re.search(r'sha256:(?P<id>[a-z0-9]{64})', result.body):
                image_id = re.findall(r'sha256:(?P<id>[a-z0-9]{64})',
                                      result.body)[-1]

        # if there is a failure message or if there is not an image id in the
        # response then throw an exception.
        if image_id is None:
            raise DockerException(None, 'failed to install image')

        image = ContainerImage(
            id=image_id,
            name=path,
            path=path,
            version=None,
            driver=self.connection.driver,
            extra={})
        return image

    def list_images(self):
        """
        List the installed container images

        :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
        """
        result = self.connection.request('/v%s/images/json' %
                                         (self.version)).object
        images = []
        for image in result:
            try:
                name = image.get('RepoTags')[0]
            except Exception:
                name = image.get('Id')
            images.append(ContainerImage(
                id=image.get('Id'),
                name=name,
                path=name,
                version=None,
                driver=self.connection.driver,
                extra={
                    "created": image.get('Created'),
                    "size": image.get('Size'),
                    "virtual_size": image.get('VirtualSize'),
                },
            ))

        return images

    def list_containers(self, image=None, all=True):
        """
        List the deployed container images

        :param image: Filter to containers with a certain image
        :type  image: :class:`libcloud.container.base.ContainerImage`

        :param all: Show all container (including stopped ones)
        :type  all: ``bool``

        :rtype: ``list`` of :class:`libcloud.container.base.Container`
        """
        if all:
            ex = '?all=1'
        else:
            ex = ''
        try:
            result = self.connection.request(
                "/v%s/containers/json%s" % (self.version, ex)).object
        except Exception as exc:
            errno = getattr(exc, 'errno', None)
            if errno == 111:
                raise DockerException(
                    errno,
                    'Make sure docker host is accessible'
                    'and the API port is correct')
            raise

        containers = [self._to_container(value) for value in result]
        return containers

    def deploy_container(self, name, image, parameters=None, start=True,
                         command=None, hostname=None, user='',
                         stdin_open=True, tty=True,
                         mem_limit=0, ports=None, environment=None, dns=None,
                         volumes=None, volumes_from=None,
                         network_disabled=False, entrypoint=None,
                         cpu_shares=None, working_dir='', domainname=None,
                         memswap_limit=0, port_bindings=None,
                         network_mode='bridge', labels=None):
        """
        Deploy an installed container image

        For details on the additional parameters see : http://bit.ly/1PjMVKV

        :param name: The name of the new container
        :type  name: ``str``

        :param image: The container image to deploy
        :type  image: :class:`libcloud.container.base.ContainerImage`

        :param parameters: Container Image parameters
        :type  parameters: ``str``

        :param start: Start the container on deployment
        :type  start: ``bool``

        :rtype: :class:`Container`
        """
        command = shlex.split(str(command))
        if port_bindings is None:
            port_bindings = {}
        params = {
            'name': name
        }

        payload = {
            'Hostname': hostname,
            'Domainname': domainname,
            'ExposedPorts': ports,
            'User': user,
            'Tty': tty,
            'OpenStdin': stdin_open,
            'StdinOnce': False,
            'Memory': mem_limit,
            'AttachStdin': True,
            'AttachStdout': True,
            'AttachStderr': True,
            'Env': environment,
            'Cmd': command,
            'Dns': dns,
            'Image': image.name,
            'Volumes': volumes,
            'VolumesFrom': volumes_from,
            'NetworkDisabled': network_disabled,
            'Entrypoint': entrypoint,
            'CpuShares': cpu_shares,
            'WorkingDir': working_dir,
            'MemorySwap': memswap_limit,
            'PublishAllPorts': True,
            'PortBindings': port_bindings,
            'NetworkMode': network_mode,
            'Labels': labels,
        }

        data = json.dumps(payload)
        try:
            result = self.connection.request('/v%s/containers/create'
                                             % (self.version),
                                             data=data,
                                             params=params, method='POST')
        except Exception as e:
            message = e.message or str(e)  # pylint: disable=no-member
            if message.startswith('No such image:'):
                raise DockerException(None, 'No such image: %s' % image.name)
            else:
                raise DockerException(None, e)

        id_ = result.object['Id']

        payload = {
            'Binds': [],
            'PublishAllPorts': True,
            'PortBindings': port_bindings,
        }

        data = json.dumps(payload)
        if start:
            if float(self._get_api_version()) > 1.22:
                result = self.connection.request(
                    '/v%s/containers/%s/start' %
                    (self.version, id_),
                    method='POST')
            else:
                result = self.connection.request(
                    '/v%s/containers/%s/start' %
                    (self.version, id_), data=data,
                    method='POST')

        return self.get_container(id_)

    def get_container(self, id):
        """
        Get a container by ID

        :param id: The ID of the container to get
        :type  id: ``str``

        :rtype: :class:`libcloud.container.base.Container`
        """
        result = self.connection.request("/v%s/containers/%s/json" %
                                         (self.version, id)).object

        return self._to_container(result)

    def start_container(self, container):
        """
        Start a container

        :param container: The container to be started
        :type  container: :class:`libcloud.container.base.Container`

        :return: The container refreshed with current data
        :rtype: :class:`libcloud.container.base.Container`
        """
        if float(self._get_api_version()) > 1.22:
            result = self.connection.request(
                '/v%s/containers/%s/start' %
                (self.version, container.id),
                method='POST')
        else:
            payload = {
                'Binds': [],
                'PublishAllPorts': True,
            }
            data = json.dumps(payload)
            result = self.connection.request(
                '/v%s/containers/%s/start' %
                (self.version, container.id),
                method='POST', data=data)

        if result.status in VALID_RESPONSE_CODES:
            return self.get_container(container.id)
        else:
            raise DockerException(result.status,
                                  'failed to start container')

    def stop_container(self, container):
        """
        Stop a container

        :param container: The container to be stopped
        :type  container: :class:`libcloud.container.base.Container`

        :return: The container refreshed with current data
        :rtype: :class:`libcloud.container.base.Container`
        """
        result = self.connection.request('/v%s/containers/%s/stop' %
                                         (self.version, container.id),
                                         method='POST')
        if result.status in VALID_RESPONSE_CODES:
            return self.get_container(container.id)
        else:
            raise DockerException(result.status,
                                  'failed to stop container')

    def restart_container(self, container):
        """
        Restart a container

        :param container: The container to be stopped
        :type  container: :class:`libcloud.container.base.Container`

        :return: The container refreshed with current data
        :rtype: :class:`libcloud.container.base.Container`
        """
        data = json.dumps({'t': 10})
        # number of seconds to wait before killing the container
        result = self.connection.request('/v%s/containers/%s/restart' %
                                         (self.version, container.id),
                                         data=data, method='POST')
        if result.status in VALID_RESPONSE_CODES:
            return self.get_container(container.id)
        else:
            raise DockerException(result.status,
                                  'failed to restart container')

    def destroy_container(self, container):
        """
        Remove a container

        :param container: The container to be destroyed
        :type  container: :class:`libcloud.container.base.Container`

        :return: True if the destroy was successful, False otherwise.
        :rtype: ``bool``
        """
        result = self.connection.request('/v%s/containers/%s' % (self.version,
                                                                 container.id),
                                         method='DELETE')
        return result.status in VALID_RESPONSE_CODES

    def ex_list_processes(self, container):
        """
        List processes running inside a container

        :param container: The container to list processes for.
        :type  container: :class:`libcloud.container.base.Container`

        :rtype: ``str``
        """
        result = self.connection.request("/v%s/containers/%s/top" %
                                         (self.version, container.id)).object

        return result

    def ex_rename_container(self, container, name):
        """
        Rename a container

        :param container: The container to be renamed
        :type  container: :class:`libcloud.container.base.Container`

        :param name: The new name
        :type  name: ``str``

        :rtype: :class:`libcloud.container.base.Container`
        """
        result = self.connection.request('/v%s/containers/%s/rename?name=%s'
                                         % (self.version, container.id, name),
                                         method='POST')
        if result.status in VALID_RESPONSE_CODES:
            return self.get_container(container.id)

    def ex_get_logs(self, container, stream=False):
        """
        Get container logs

        If stream == True, logs will be yielded as a stream
        From Api Version 1.11 and above we need a GET request to get the logs
        Logs are in different format of those of Version 1.10 and below

        :param container: The container to list logs for
        :type  container: :class:`libcloud.container.base.Container`

        :param stream: Stream the output
        :type  stream: ``bool``

        :rtype: ``bool``
        """
        payload = {}
        data = json.dumps(payload)

        if float(self._get_api_version()) > 1.10:
            result = self.connection.request(
                "/v%s/containers/%s/logs?follow=%s&stdout=1&stderr=1" %
                (self.version, container.id, str(stream))).object
            logs = result
        else:
            result = self.connection.request(
                "/v%s/containers/%s/attach?logs=1&stream=%s&stdout=1&stderr=1"
                % (self.version, container.id, str(stream)),
                method='POST',
                data=data)
            logs = result.body

        return logs

    def ex_search_images(self, term):
        """Search for an image on Docker.io.
           Returns a list of ContainerImage objects

           >>> images = conn.ex_search_images(term='mistio')
           >>> images
           [<ContainerImage: id=rolikeusch/docker-mistio...>,
            <ContainerImage: id=mist/mistio, name=mist/mistio,
                driver=Docker  ...>]

            :param term: The search term
            :type  term: ``str``

            :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
        """

        term = term.replace(' ', '+')
        result = self.connection.request('/v%s/images/search?term=%s' %
                                         (self.version, term)).object
        images = []
        for image in result:
            name = image.get('name')
            images.append(
                ContainerImage(
                    id=name,
                    path=name,
                    version=None,
                    name=name,
                    driver=self.connection.driver,
                    extra={
                        "description": image.get('description'),
                        "is_official": image.get('is_official'),
                        "is_trusted": image.get('is_trusted'),
                        "star_count": image.get('star_count'),
                    },
                ))

        return images

    def ex_delete_image(self, image):
        """
        Remove image from the filesystem

        :param  image: The image to remove
        :type   image: :class:`libcloud.container.base.ContainerImage`

        :rtype: ``bool``
        """
        result = self.connection.request('/v%s/images/%s' % (self.version,
                                                             image.name),
                                         method='DELETE')
        return result.status in VALID_RESPONSE_CODES

    def _to_container(self, data):
        """
        Convert container in Container instances
        """
        try:
            name = data.get('Name').strip('/')
        except Exception:
            try:
                name = data.get('Names')[0].strip('/')
            except Exception:
                name = data.get('Id')
        state = data.get('State')
        if isinstance(state, dict):
            status = data.get(
                'Status',
                state.get('Status')
                if state is not None else None)
        else:
            status = data.get('Status')
        if 'Exited' in status:
            state = ContainerState.STOPPED
        elif status.startswith('Up '):
            state = ContainerState.RUNNING
        elif 'running' in status:
            state = ContainerState.RUNNING
        else:
            state = ContainerState.STOPPED
        image = data.get('Image')
        ports = data.get('Ports', [])
        created = data.get('Created')
        if isinstance(created, float):
            created = ts_to_str(created)
        extra = {
            'id': data.get('Id'),
            'status': data.get('Status'),
            'created': created,
            'image': image,
            'ports': ports,
            'command': data.get('Command'),
            'sizerw': data.get('SizeRw'),
            'sizerootfs': data.get('SizeRootFs'),
        }
        ips = []
        if ports is not None:
            for port in ports:
                if port.get('IP') is not None:
                    ips.append(port.get('IP'))
        return Container(
            id=data['Id'],
            name=name,
            image=ContainerImage(
                id=data.get('ImageID', None),
                path=image,
                name=image,
                version=None,
                driver=self.connection.driver
            ),
            ip_addresses=ips,
            state=state,
            driver=self.connection.driver,
            extra=extra)

    def _get_api_version(self):
        """
        Get the docker API version information
        """
        result = self.connection.request('/version').object
        result = result or {}
        api_version = result.get('ApiVersion')

        return api_version


def ts_to_str(timestamp):
    """
    Return a timestamp as a nicely formated datetime string.
    """
    date = datetime.datetime.fromtimestamp(timestamp)
    date_string = date.strftime("%d/%m/%Y %H:%M %Z")
    return date_string
