# 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.
"""
DigitalOcean Driver
"""
import json
import warnings

from libcloud.utils.iso8601 import parse_date
from libcloud.utils.py3 import httplib

from libcloud.common.digitalocean import DigitalOcean_v1_BaseDriver
from libcloud.common.digitalocean import DigitalOcean_v2_BaseDriver
from libcloud.common.types import InvalidCredsError
from libcloud.compute.types import Provider, NodeState
from libcloud.compute.base import NodeImage, NodeSize, NodeLocation, KeyPair
from libcloud.compute.base import Node, NodeDriver

__all__ = [
    'DigitalOceanNodeDriver',
    'DigitalOcean_v1_NodeDriver',
    'DigitalOcean_v2_NodeDriver'
]


class DigitalOceanNodeDriver(NodeDriver):
    """
    DigitalOcean NodeDriver defaulting to using APIv2.

    :keyword    key: Required for authentication. Used in both ``v1`` and
                     ``v2`` implementations.
    :type       key: ``str``

    :keyword    secret: Used in driver authentication with key. Defaults to
                        None and when set, will cause driver to use ``v1`` for
                        connection and response. (optional)
    :type       secret: ``str``

    :keyword    api_version: Specifies the API version to use. ``v1`` and
                             ``v2`` are the only valid options. Defaults to
                             using ``v2`` (optional)
    :type       api_version: ``str``
    """
    type = Provider.DIGITAL_OCEAN
    name = 'DigitalOcean'
    website = 'https://www.digitalocean.com'

    def __new__(cls, key, secret=None, api_version='v2', **kwargs):
        if cls is DigitalOceanNodeDriver:
            if api_version == 'v1' or secret is not None:
                if secret is None:
                    raise InvalidCredsError(
                        'secret missing for v1 authentication')
                if secret is not None and api_version == 'v2':
                    raise InvalidCredsError(
                        'secret not accepted for v2 authentication')
                cls = DigitalOcean_v1_NodeDriver
            elif api_version == 'v2':
                cls = DigitalOcean_v2_NodeDriver
            else:
                raise NotImplementedError('Unsupported API version: %s' %
                                          (api_version))
        return super(DigitalOceanNodeDriver, cls).__new__(cls, **kwargs)


# TODO Implement v1 driver using KeyPair
class SSHKey(object):
    def __init__(self, id, name, pub_key):
        self.id = id
        self.name = name
        self.pub_key = pub_key

    def __repr__(self):
        return (('<SSHKey: id=%s, name=%s, pub_key=%s>') %
                (self.id, self.name, self.pub_key))


class DigitalOcean_v1_NodeDriver(DigitalOcean_v1_BaseDriver,
                                 DigitalOceanNodeDriver):
    """
    DigitalOcean NodeDriver using v1 of the API.
    """

    NODE_STATE_MAP = {'new': NodeState.PENDING,
                      'off': NodeState.REBOOTING,
                      'active': NodeState.RUNNING}

    def list_nodes(self):
        data = self.connection.request('/v1/droplets').object['droplets']
        return list(map(self._to_node, data))

    def list_locations(self):
        data = self.connection.request('/v1/regions').object['regions']
        return list(map(self._to_location, data))

    def list_images(self):
        data = self.connection.request('/v1/images').object['images']
        return list(map(self._to_image, data))

    def list_sizes(self):
        data = self.connection.request('/v1/sizes').object['sizes']
        return list(map(self._to_size, data))

    def create_node(self, name, size, image, location, ex_ssh_key_ids=None):
        """
        Create a node.

        :keyword    ex_ssh_key_ids: A list of ssh key ids which will be added
                                   to the server. (optional)
        :type       ex_ssh_key_ids: ``list`` of ``str``

        :return: The newly created node.
        :rtype: :class:`Node`
        """
        params = {'name': name, 'size_id': size.id, 'image_id': image.id,
                  'region_id': location.id}

        if ex_ssh_key_ids:
            params['ssh_key_ids'] = ','.join(ex_ssh_key_ids)

        data = self.connection.request('/v1/droplets/new', params=params)

        # TODO: Handle this in the response class
        status = data.object.get('status', 'OK')
        if status == 'ERROR':
            message = data.object.get('message', None)
            error_message = data.object.get('error_message', message)
            raise ValueError('Failed to create node: %s' % (error_message))

        return self._to_node(data=data.object['droplet'])

    def reboot_node(self, node):
        res = self.connection.request('/v1/droplets/%s/reboot/' % (node.id))
        return res.status == httplib.OK

    def destroy_node(self, node):
        params = {'scrub_data': '1'}
        res = self.connection.request('/v1/droplets/%s/destroy/' % (node.id),
                                      params=params)
        return res.status == httplib.OK

    def ex_rename_node(self, node, name):
        params = {'name': name}
        res = self.connection.request('/v1/droplets/%s/rename/' % (node.id),
                                      params=params)
        return res.status == httplib.OK

    def list_key_pairs(self):
        """
        List all the available SSH keys.

        :return: Available SSH keys.
        :rtype: ``list`` of :class:`KeyPair`
        """
        data = self.connection.request('/v1/ssh_keys').object['ssh_keys']
        return list(map(self._to_key_pair, data))

    def ex_list_ssh_keys(self):
        """
        List all the available SSH keys.
        :return: Available SSH keys.
        :rtype: ``list`` of :class:`SSHKey`
        """
        warnings.warn("This method has been deprecated in "
                      "favor of the list_key_pairs method")

        data = self.connection.request('/v1/ssh_keys').object['ssh_keys']
        return list(map(self._to_ssh_key, data))

    def get_key_pair(self, name):
        """
        Retrieve a single key pair.

        :param name: Name of the key pair to retrieve.
        :type name: ``str``

        :rtype: :class:`.KeyPair`
        """
        qkey = [k for k in self.list_key_pairs() if k.name == name][0]
        data = self.connection.request('/v1/ssh_keys/%s' %
                                       qkey.extra['id']).object['ssh_key']
        return self._to_key_pair(data=data)

    # TODO: This adds the ssh_key_pub parameter. This puts the burden of making
    #      it within the function or on the API. The KeyPair API needs work.
    def create_key_pair(self, name, ssh_key_pub):
        """
        Create a new SSH key.

        :param      name: Key name (required)
        :type       name: ``str``

        :param      name: Valid public key string (required)
        :type       name: ``str``
        """
        params = {'name': name, 'ssh_pub_key': ssh_key_pub}
        data = self.connection.request('/v1/ssh_keys/new/', method='GET',
                                       params=params).object
        assert 'ssh_key' in data
        # TODO: libcloud.compute.base.KeyPair.create_key_pair doesn't specify
        #      a return value. This looks like it should return a KeyPair
        return self._to_key_pair(data=data['ssh_key'])

    def ex_create_ssh_key(self, name, ssh_key_pub):
        """
        Create a new SSH key.
        :param      name: Key name (required)
        :type       name: ``str``
        :param      name: Valid public key string (required)
        :type       name: ``str``
        """
        warnings.warn("This method has been deprecated in "
                      "favor of the create_key_pair method")

        params = {'name': name, 'ssh_pub_key': ssh_key_pub}
        data = self.connection.request('/v1/ssh_keys/new/', method='GET',
                                       params=params).object
        assert 'ssh_key' in data
        return self._to_ssh_key(data=data['ssh_key'])

    def delete_key_pair(self, key_pair):
        """
        Delete an existing key pair.

        :param key_pair: Key pair object.
        :type key_pair: :class:`.KeyPair`
        """
        res = self.connection.request('/v1/ssh_keys/%s/destroy/' %
                                      key_pair.extra['id'])
        # TODO: This looks like it should return bool like the other delete_*
        return res.status == httplib.OK

    def ex_destroy_ssh_key(self, key_id):
        """
        Delete an existing SSH key.
        :param      key_id: SSH key id (required)
        :type       key_id: ``str``
        """
        warnings.warn(
            "This method has been deprecated in "
            "favor of the delete_key_pair method")

        res = self.connection.request('/v1/ssh_keys/%s/destroy/' % (key_id))
        return res.status == httplib.OK

    def _to_node(self, data):
        extra_keys = ['backups_active', 'region_id', 'image_id', 'size_id']
        if 'status' in data:
            state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
        else:
            state = NodeState.UNKNOWN

        if 'ip_address' in data and data['ip_address'] is not None:
            public_ips = [data['ip_address']]
        else:
            public_ips = []

        extra = {}
        for key in extra_keys:
            if key in data:
                extra[key] = data[key]

        node = Node(id=data['id'], name=data['name'], state=state,
                    public_ips=public_ips, private_ips=None, extra=extra,
                    driver=self)
        return node

    def _to_image(self, data):
        extra = {'distribution': data['distribution']}
        return NodeImage(id=data['id'], name=data['name'], extra=extra,
                         driver=self)

    def _to_location(self, data):
        return NodeLocation(id=data['id'], name=data['name'], country=None,
                            driver=self)

    def _to_size(self, data):
        ram = data['name'].lower()

        if 'mb' in ram:
            ram = int(ram.replace('mb', ''))
        elif 'gb' in ram:
            ram = int(ram.replace('gb', '')) * 1024

        return NodeSize(id=data['id'], name=data['name'], ram=ram, disk=0,
                        bandwidth=0, price=0, driver=self)

    def _to_key_pair(self, data):
        try:
            pubkey = data['ssh_pub_key']
        except KeyError:
            pubkey = None
        return KeyPair(data['name'], public_key=pubkey, fingerprint=None,
                       driver=self, private_key=None, extra={'id': data['id']})

    def _to_ssh_key(self, data):
        return SSHKey(id=data['id'], name=data['name'],
                      pub_key=data.get('ssh_pub_key', None))


class DigitalOcean_v2_NodeDriver(DigitalOcean_v2_BaseDriver,
                                 DigitalOceanNodeDriver):
    """
    DigitalOcean NodeDriver using v2 of the API.
    """

    NODE_STATE_MAP = {'new': NodeState.PENDING,
                      'off': NodeState.STOPPED,
                      'active': NodeState.RUNNING,
                      'archive': NodeState.TERMINATED}

    EX_CREATE_ATTRIBUTES = ['backups',
                            'ipv6',
                            'private_networking',
                            'ssh_keys']

    def list_images(self):
        data = self._paginated_request('/v2/images', 'images')
        return list(map(self._to_image, data))

    def list_key_pairs(self):
        """
        List all the available SSH keys.

        :return: Available SSH keys.
        :rtype: ``list`` of :class:`KeyPair`
        """
        data = self._paginated_request('/v2/account/keys', 'ssh_keys')
        return list(map(self._to_key_pair, data))

    def list_locations(self):
        data = self._paginated_request('/v2/regions', 'regions')
        return list(map(self._to_location, data))

    def list_nodes(self):
        data = self._paginated_request('/v2/droplets', 'droplets')
        return list(map(self._to_node, data))

    def list_sizes(self):
        data = self._paginated_request('/v2/sizes', 'sizes')
        return list(map(self._to_size, data))

    def create_node(self, name, size, image, location, ex_create_attr=None,
                    ex_ssh_key_ids=None, ex_user_data=None):
        """
        Create a node.

        The `ex_create_attr` parameter can include the following dictionary
        key and value pairs:

        * `backups`: ``bool`` defaults to False
        * `ipv6`: ``bool`` defaults to False
        * `private_networking`: ``bool`` defaults to False
        * `user_data`: ``str`` for cloud-config data
        * `ssh_keys`: ``list`` of ``int`` key ids or ``str`` fingerprints

        `ex_create_attr['ssh_keys']` will override `ex_ssh_key_ids` assignment.

        :keyword ex_create_attr: A dictionary of optional attributes for
                                 droplet creation
        :type ex_create_attr: ``dict``

        :keyword ex_ssh_key_ids: A list of ssh key ids which will be added
                                 to the server. (optional)
        :type ex_ssh_key_ids: ``list`` of ``int`` key ids or ``str``
                              key fingerprints

        :keyword    ex_user_data:  User data to be added to the node on create.
                                     (optional)
        :type       ex_user_data:  ``str``

        :return: The newly created node.
        :rtype: :class:`Node`
        """
        attr = {'name': name, 'size': size.name, 'image': image.id,
                'region': location.id, 'user_data': ex_user_data}

        if ex_ssh_key_ids:
            warnings.warn("The ex_ssh_key_ids parameter has been deprecated in"
                          " favor of the ex_create_attr parameter.")
            attr['ssh_keys'] = ex_ssh_key_ids

        ex_create_attr = ex_create_attr or {}
        for key in ex_create_attr.keys():
            if key in self.EX_CREATE_ATTRIBUTES:
                attr[key] = ex_create_attr[key]

        res = self.connection.request('/v2/droplets',
                                      data=json.dumps(attr), method='POST')

        data = res.object['droplet']
        # TODO: Handle this in the response class
        status = res.object.get('status', 'OK')
        if status == 'ERROR':
            message = res.object.get('message', None)
            error_message = res.object.get('error_message', message)
            raise ValueError('Failed to create node: %s' % (error_message))

        return self._to_node(data=data)

    def destroy_node(self, node):
        res = self.connection.request('/v2/droplets/%s' % (node.id),
                                      method='DELETE')
        return res.status == httplib.NO_CONTENT

    def reboot_node(self, node):
        attr = {'type': 'reboot'}
        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
                                      data=json.dumps(attr), method='POST')
        return res.status == httplib.CREATED

    def create_image(self, node, name):
        """
        Create an image from a Node.

        @inherits: :class:`NodeDriver.create_image`

        :param node: Node to use as base for image
        :type node: :class:`Node`

        :param node: Name for image
        :type node: ``str``

        :rtype: ``bool``
        """
        attr = {'type': 'snapshot', 'name': name}
        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
                                      data=json.dumps(attr), method='POST')
        return res.status == httplib.CREATED

    def delete_image(self, image):
        """Delete an image for node.

        @inherits: :class:`NodeDriver.delete_image`

        :param      image: the image to be deleted
        :type       image: :class:`NodeImage`

        :rtype: ``bool``
        """
        res = self.connection.request('/v2/images/%s' % (image.id),
                                      method='DELETE')
        return res.status == httplib.NO_CONTENT

    def ex_get_creation_time(self, node):
        """
        Return the date and time that represent when the Instance was created.
        :param      node: Node instance
        :type       node: :class:`Node`

        :return: ISO8601 combined date and time format string for when the
         Droplet was created.
        :rtype: ``str``
        """
        return node.extra['created_at']

    def get_image(self, image_id):
        """
        Get an image based on an image_id

        @inherits: :class:`NodeDriver.get_image`

        :param image_id: Image identifier
        :type image_id: ``int``

        :return: A NodeImage object
        :rtype: :class:`NodeImage`
        """
        data = self._paginated_request('/v2/images/%s' % (image_id), 'image')
        return self._to_image(data)

    def ex_rename_node(self, node, name):
        attr = {'type': 'rename', 'name': name}
        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
                                      data=json.dumps(attr), method='POST')
        return res.status == httplib.CREATED

    def ex_shutdown_node(self, node):
        attr = {'type': 'shutdown'}
        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
                                      data=json.dumps(attr), method='POST')
        return res.status == httplib.CREATED

    def ex_power_on_node(self, node):
        attr = {'type': 'power_on'}
        res = self.connection.request('/v2/droplets/%s/actions' % (node.id),
                                      data=json.dumps(attr), method='POST')
        return res.status == httplib.CREATED

    def create_key_pair(self, name, public_key=''):
        """
        Create a new SSH key.

        :param      name: Key name (required)
        :type       name: ``str``

        :param      public_key: Valid public key string (required)
        :type       public_key: ``str``
        """
        attr = {'name': name, 'public_key': public_key}
        res = self.connection.request('/v2/account/keys', method='POST',
                                      data=json.dumps(attr))

        data = res.object['ssh_key']

        return self._to_key_pair(data=data)

    def delete_key_pair(self, key):
        """
        Delete an existing SSH key.

        :param      key: SSH key (required)
        :type       key: :class:`KeyPair`
        """
        key_id = key.extra['id']
        res = self.connection.request('/v2/account/keys/%s' % (key_id),
                                      method='DELETE')
        return res.status == httplib.NO_CONTENT

    def get_key_pair(self, name):
        """
        Retrieve a single key pair.

        :param name: Name of the key pair to retrieve.
        :type name: ``str``

        :rtype: :class:`.KeyPair`
        """
        qkey = [k for k in self.list_key_pairs() if k.name == name][0]
        data = self.connection.request('/v2/account/keys/%s' %
                                       qkey.extra['id']).object['ssh_key']
        return self._to_key_pair(data=data)

    def _to_node(self, data):
        extra_keys = ['memory', 'vcpus', 'disk', 'region', 'image',
                      'size_slug', 'locked', 'created_at', 'networks',
                      'kernel', 'backup_ids', 'snapshot_ids', 'features']
        if 'status' in data:
            state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
        else:
            state = NodeState.UNKNOWN

        created = parse_date(data['created_at'])
        networks = data['networks']
        private_ips = []
        public_ips = []
        if networks:
            for net in networks['v4']:
                if net['type'] == 'private':
                    private_ips = [net['ip_address']]
                if net['type'] == 'public':
                    public_ips = [net['ip_address']]

        extra = {}
        for key in extra_keys:
            if key in data:
                extra[key] = data[key]

        node = Node(id=data['id'], name=data['name'], state=state,
                    public_ips=public_ips, private_ips=private_ips,
                    created_at=created, driver=self, extra=extra)
        return node

    def _to_image(self, data):
        extra = {'distribution': data['distribution'],
                 'public': data['public'],
                 'slug': data['slug'],
                 'regions': data['regions'],
                 'min_disk_size': data['min_disk_size'],
                 'created_at': data['created_at']}
        return NodeImage(id=data['id'], name=data['name'], driver=self,
                         extra=extra)

    def _to_location(self, data):
        return NodeLocation(id=data['slug'], name=data['name'], country=None,
                            driver=self)

    def _to_size(self, data):
        extra = {'vcpus': data['vcpus'],
                 'regions': data['regions']}
        return NodeSize(id=data['slug'], name=data['slug'], ram=data['memory'],
                        disk=data['disk'], bandwidth=data['transfer'],
                        price=data['price_hourly'], driver=self, extra=extra)

    def _to_key_pair(self, data):
        extra = {'id': data['id']}
        return KeyPair(name=data['name'],
                       fingerprint=data['fingerprint'],
                       public_key=data['public_key'],
                       private_key=None,
                       driver=self,
                       extra=extra)
