# 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 os
import ssl
import copy
import json
import time
import socket
import binascii
from typing import Any, Dict, Type, Union, Optional

import libcloud
from libcloud.http import LibcloudConnection, HttpLibResponseProxy
from libcloud.utils.py3 import ET, httplib, urlparse, urlencode
from libcloud.utils.misc import lowercase_keys
from libcloud.utils.retry import Retry
from libcloud.common.types import LibcloudError, MalformedResponseError
from libcloud.common.exceptions import exception_from_message

__all__ = [
    "RETRY_FAILED_HTTP_REQUESTS",
    "BaseDriver",
    "Connection",
    "PollingConnection",
    "ConnectionKey",
    "ConnectionUserAndKey",
    "CertificateConnection",
    "Response",
    "HTTPResponse",
    "JsonResponse",
    "XmlResponse",
    "RawResponse",
]

# Module level variable indicates if the failed HTTP requests should be retried
RETRY_FAILED_HTTP_REQUESTS = False

# Set to True to allow double slashes in the URL path. This way
# morph_action_hook() won't strip potentially double slashes in the URLs.
# This is to support scenarios such as this one -
# https://github.com/apache/libcloud/issues/1529.
# We default it to False for backward compatibility reasons.
ALLOW_PATH_DOUBLE_SLASHES = False


class LazyObject:
    """An object that doesn't get initialized until accessed."""

    @classmethod
    def _proxy(cls, *lazy_init_args, **lazy_init_kwargs):
        class Proxy(cls):
            _lazy_obj = None

            def __init__(self):
                # Must override the lazy_cls __init__
                pass

            def __getattribute__(self, attr):
                lazy_obj = object.__getattribute__(self, "_get_lazy_obj")()
                return getattr(lazy_obj, attr)

            def __setattr__(self, attr, value):
                lazy_obj = object.__getattribute__(self, "_get_lazy_obj")()
                setattr(lazy_obj, attr, value)

            def _get_lazy_obj(self):
                lazy_obj = object.__getattribute__(self, "_lazy_obj")
                if lazy_obj is None:
                    lazy_obj = cls(*lazy_init_args, **lazy_init_kwargs)
                    object.__setattr__(self, "_lazy_obj", lazy_obj)
                return lazy_obj

        return Proxy()

    @classmethod
    def lazy(cls, *lazy_init_args, **lazy_init_kwargs):
        """Create a lazily instantiated instance of the subclass, cls."""
        return cls._proxy(*lazy_init_args, **lazy_init_kwargs)


class HTTPResponse(httplib.HTTPResponse):
    # On python 2.6 some calls can hang because HEAD isn't quite properly
    # supported.
    # In particular this happens on S3 when calls are made to get_object to
    # objects that don't exist.
    # This applies the behaviour from 2.7, fixing the hangs.
    def read(self, amt=None):
        if self.fp is None:
            return ""

        if self._method == "HEAD":
            self.close()
            return ""

        return httplib.HTTPResponse.read(self, amt)


class Response:
    """
    A base Response class to derive from.
    """

    # Response status code
    status = httplib.OK  # type: int
    # Response headers
    headers = {}  # type: dict

    # Raw response body
    body = None

    # Parsed response body
    object = None

    error = None  # Reason returned by the server.
    connection = None  # Parent connection class
    parse_zero_length_body = False

    def __init__(self, response, connection):
        """
        :param response: HTTP response object. (optional)
        :type response: :class:`httplib.HTTPResponse`

        :param connection: Parent connection object.
        :type connection: :class:`.Connection`
        """
        self.connection = connection

        # http.client In Python 3 doesn't automatically lowercase the header
        # names
        self.headers = lowercase_keys(dict(response.headers))
        self.error = response.reason
        self.status = response.status_code
        self.request = response.request
        self.iter_content = response.iter_content

        self.body = (
            response.text.strip()
            if response.text is not None and hasattr(response.text, "strip")
            else ""
        )

        if not self.success():
            raise exception_from_message(
                code=self.status, message=self.parse_error(), headers=self.headers
            )

        self.object = self.parse_body()

    def parse_body(self):
        """
        Parse response body.

        Override in a provider's subclass.

        :return: Parsed body.
        :rtype: ``str``
        """
        return self.body if self.body is not None else ""

    def parse_error(self):
        """
        Parse the error messages.

        Override in a provider's subclass.

        :return: Parsed error.
        :rtype: ``str``
        """
        return self.body

    def success(self):
        """
        Determine if our request was successful.

        The meaning of this can be arbitrary; did we receive OK status? Did
        the node get created? Were we authenticated?

        :rtype: ``bool``
        :return: ``True`` or ``False``
        """
        # pylint: disable=E1101
        import requests

        return self.status in [
            requests.codes.ok,
            requests.codes.created,
            httplib.OK,
            httplib.CREATED,
            httplib.ACCEPTED,
        ]


class JsonResponse(Response):
    """
    A Base JSON Response class to derive from.
    """

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

        try:
            body = json.loads(self.body)
        except Exception:
            raise MalformedResponseError(
                "Failed to parse JSON", body=self.body, driver=self.connection.driver
            )
        return body

    parse_error = parse_body


class XmlResponse(Response):
    """
    A Base XML Response class to derive from.
    """

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

        try:
            try:
                body = ET.XML(self.body)
            except ValueError:
                # lxml wants a bytes and tests are basically hard-coded to str
                body = ET.XML(self.body.encode("utf-8"))
        except Exception:
            raise MalformedResponseError(
                "Failed to parse XML", body=self.body, driver=self.connection.driver
            )
        return body

    parse_error = parse_body


class RawResponse(Response):
    def __init__(self, connection, response=None):
        """
        :param connection: Parent connection object.
        :type connection: :class:`.Connection`
        """
        self._status = None
        self._response = None
        self._headers = {}
        self._error = None
        self._reason = None
        self.connection = connection
        if response is not None:
            self.headers = lowercase_keys(dict(response.headers))
            self.error = response.reason
            self.status = response.status_code
            self.request = response.request
            self.iter_content = response.iter_content

        if not self.success():
            self.parse_error()

    def success(self):
        """
        Determine if our request was successful.

        The meaning of this can be arbitrary; did we receive OK status? Did
        the node get created? Were we authenticated?

        :rtype: ``bool``
        :return: ``True`` or ``False``
        """
        # pylint: disable=E1101
        import requests

        return self.status in [
            requests.codes.ok,
            requests.codes.created,
            httplib.OK,
            httplib.CREATED,
            httplib.ACCEPTED,
        ]

    @property
    def response(self):
        if not self._response:
            response = self.connection.connection.getresponse()
            self._response = HttpLibResponseProxy(response)
            if not self.success():
                self.parse_error()
        return self._response

    @property
    def body(self):
        # Note: We use property to avoid saving whole response body into RAM
        # See https://github.com/apache/libcloud/pull/1132 for details
        return self.response.body

    @property
    def reason(self):
        if not self._reason:
            self._reason = self.response.reason
        return self._reason


class Connection:
    """
    A Base Connection class to derive from.
    """

    conn_class = LibcloudConnection

    responseCls = Response
    rawResponseCls = RawResponse
    retryCls = Retry
    connection = None
    host = "127.0.0.1"  # type: str
    port = 443
    timeout = None  # type: Optional[Union[int, float]]
    secure = 1
    driver = None  # type:  Type[BaseDriver]
    action = None
    cache_busting = False
    backoff = None
    retry_delay = None

    allow_insecure = True

    def __init__(
        self,
        secure=True,
        host=None,
        port=None,
        url=None,
        timeout=None,
        proxy_url=None,
        retry_delay=None,
        backoff=None,
    ):
        self.secure = secure and 1 or 0
        self.ua = []
        self.context = {}

        if not self.allow_insecure and not secure:
            # TODO: We should eventually switch to whitelist instead of
            # blacklist approach
            raise ValueError("Non https connections are not allowed (use " "secure=True)")

        self.request_path = ""

        if host:
            self.host = host

        if port is not None:
            self.port = port
        else:
            if self.secure == 1:
                self.port = 443
            else:
                self.port = 80

        if url:
            (
                self.host,
                self.port,
                self.secure,
                self.request_path,
            ) = self._tuple_from_url(url)

        self.timeout = timeout or self.timeout
        self.retry_delay = retry_delay
        self.backoff = backoff
        self.proxy_url = proxy_url

    def set_http_proxy(self, proxy_url):
        """
        Set a HTTP / HTTPS proxy which will be used with this connection.

        :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without
                          authentication and
                          <scheme>://<username>:<password>@<hostname>:<port>
                          for basic auth authentication information.
        :type proxy_url: ``str``
        """
        self.proxy_url = proxy_url

        # NOTE: Because of the way connection instantion works, we need to call
        # self.connection.set_http_proxy() here. Just setting "self.proxy_url"
        # won't work.
        self.connection.set_http_proxy(proxy_url=proxy_url)

    def set_context(self, context):
        if not isinstance(context, dict):
            raise TypeError("context needs to be a dictionary")

        self.context = context

    def reset_context(self):
        self.context = {}

    def _tuple_from_url(self, url):
        secure = 1
        port = None
        (scheme, netloc, request_path, param, query, fragment) = urlparse.urlparse(url)

        if scheme not in ["http", "https"]:
            raise LibcloudError("Invalid scheme: {} in url {}".format(scheme, url))

        if scheme == "http":
            secure = 0

        if ":" in netloc:
            netloc, port = netloc.rsplit(":")
            port = int(port)

        if not port:
            if scheme == "http":
                port = 80
            else:
                port = 443

        host = netloc
        port = int(port)

        return (host, port, secure, request_path)

    def connect(self, host=None, port=None, base_url=None, **kwargs):
        """
        Establish a connection with the API server.

        :type host: ``str``
        :param host: Optional host to override our default

        :type port: ``int``
        :param port: Optional port to override our default

        :returns: A connection
        """
        # prefer the attribute base_url if its set or sent
        connection = None
        secure = self.secure

        if getattr(self, "base_url", None) and base_url is None:
            (host, port, secure, request_path) = self._tuple_from_url(getattr(self, "base_url"))
        elif base_url is not None:
            (host, port, secure, request_path) = self._tuple_from_url(base_url)
        else:
            host = host or self.host
            port = port or self.port

        # Make sure port is an int
        port = int(port)

        if not hasattr(kwargs, "host"):
            kwargs.update({"host": host})

        if not hasattr(kwargs, "port"):
            kwargs.update({"port": port})

        if not hasattr(kwargs, "secure"):
            kwargs.update({"secure": self.secure})

        if not hasattr(kwargs, "key_file") and hasattr(self, "key_file"):
            kwargs.update({"key_file": getattr(self, "key_file")})

        if not hasattr(kwargs, "cert_file") and hasattr(self, "cert_file"):
            kwargs.update({"cert_file": getattr(self, "cert_file")})

        if self.timeout:
            kwargs.update({"timeout": self.timeout})

        if self.proxy_url:
            kwargs.update({"proxy_url": self.proxy_url})

        connection = self.conn_class(**kwargs)
        # You can uncoment this line, if you setup a reverse proxy server
        # which proxies to your endpoint, and lets you easily capture
        # connections in cleartext when you setup the proxy to do SSL
        # for you
        # connection = self.conn_class("127.0.0.1", 8080)

        self.connection = connection

    def _user_agent(self):
        user_agent_suffix = " ".join(["(%s)" % x for x in self.ua])

        if self.driver:
            user_agent = "libcloud/{} ({}) {}".format(
                libcloud.__version__,
                self.driver.name,
                user_agent_suffix,
            )
        else:
            user_agent = "libcloud/{} {}".format(libcloud.__version__, user_agent_suffix)

        return user_agent

    def user_agent_append(self, token):
        """
        Append a token to a user agent string.

        Users of the library should call this to uniquely identify their
        requests to a provider.

        :type token: ``str``
        :param token: Token to add to the user agent.
        """
        self.ua.append(token)

    def request(
        self,
        action,
        params=None,
        data=None,
        headers=None,
        method="GET",
        raw=False,
        stream=False,
        json=None,
        retry_failed=None,
    ):
        """
        Request a given `action`.

        Basically a wrapper around the connection
        object's `request` that does some helpful pre-processing.

        :type action: ``str``
        :param action: A path. This can include arguments. If included,
            any extra parameters are appended to the existing ones.

        :type params: ``dict``
        :param params: Optional mapping of additional parameters to send. If
            None, leave as an empty ``dict``.

        :type data: ``unicode``
        :param data: A body of data to send with the request.

        :type headers: ``dict``
        :param headers: Extra headers to add to the request
            None, leave as an empty ``dict``.

        :type method: ``str``
        :param method: An HTTP method such as "GET" or "POST".

        :type raw: ``bool``
        :param raw: True to perform a "raw" request aka only send the headers
                     and use the rawResponseCls class. This is used with
                     storage API when uploading a file.

        :type stream: ``bool``
        :param stream: True to return an iterator in Response.iter_content
                    and allow streaming of the response data
                    (for downloading large files)

        :param retry_failed: True if failed requests should be retried. This
                              argument can override module level constant and
                              environment variable value on per-request basis.

        :return: An :class:`Response` instance.
        :rtype: :class:`Response` instance

        """
        if params is None:
            params = {}
        else:
            params = copy.copy(params)

        if headers is None:
            headers = {}
        else:
            headers = copy.copy(headers)

        retry_enabled = (
            os.environ.get("LIBCLOUD_RETRY_FAILED_HTTP_REQUESTS", False)
            or RETRY_FAILED_HTTP_REQUESTS
        )

        # Method level argument has precedence over module level constant and
        # environment variable
        if retry_failed is not None:
            retry_enabled = retry_failed

        action = self.morph_action_hook(action)
        self.action = action
        self.method = method
        self.data = data

        # Extend default parameters
        params = self.add_default_params(params)

        # Add cache busting parameters (if enabled)
        if self.cache_busting and method == "GET":
            params = self._add_cache_busting_to_params(params=params)

        # Extend default headers
        headers = self.add_default_headers(headers)

        # We always send a user-agent header
        headers.update({"User-Agent": self._user_agent()})

        # Indicate that we support gzip and deflate compression
        headers.update({"Accept-Encoding": "gzip,deflate"})

        port = int(self.port)

        if port not in (80, 443):
            headers.update({"Host": "%s:%d" % (self.host, port)})
        else:
            headers.update({"Host": self.host})

        if data:
            data = self.encode_data(data)

        params, headers = self.pre_connect_hook(params, headers)

        if params:
            if "?" in action:
                url = "&".join((action, urlencode(params, doseq=True)))
            else:
                url = "?".join((action, urlencode(params, doseq=True)))
        else:
            url = action

        # IF connection has not yet been established
        if self.connection is None:
            self.connect()

        request_to_be_executed = self._retryable_request

        if retry_enabled:
            retry_request = self.retryCls(
                retry_delay=self.retry_delay, timeout=self.timeout, backoff=self.backoff
            )
            request_to_be_executed = retry_request(self._retryable_request)

        return request_to_be_executed(
            url=url, method=method, raw=raw, stream=stream, headers=headers, data=data
        )

    def _retryable_request(
        self,
        url: str,
        data: bytes,
        headers: Dict[str, Any],
        method: str,
        raw: bool,
        stream: bool,
    ) -> Union[RawResponse, Response]:
        try:
            # @TODO: Should we just pass File object as body to request method
            # instead of dealing with splitting and sending the file ourselves?
            assert self.connection is not None

            if raw:
                self.connection.prepared_request(
                    method=method,
                    url=url,
                    body=data,
                    headers=headers,
                    raw=raw,
                    stream=stream,
                )
            else:
                self.connection.request(
                    method=method, url=url, body=data, headers=headers, stream=stream
                )

        except socket.gaierror as e:
            message = str(e)
            errno = getattr(e, "errno", None)

            if errno == -5:
                # Throw a more-friendly exception on "no address associated
                # with hostname" error. This error could simply indicate that
                # "host" Connection class attribute is set to an incorrect
                # value
                class_name = self.__class__.__name__
                msg = (
                    '%s. Perhaps "host" Connection class attribute '
                    "(%s.connection) is set to an invalid, non-hostname "
                    "value (%s)?" % (message, class_name, self.host)
                )
                raise socket.gaierror(msg)  # type: ignore
            self.reset_context()
            raise e
        except ssl.SSLError as e:
            self.reset_context()
            raise ssl.SSLError(str(e))

        if raw:
            responseCls = self.rawResponseCls
            kwargs = {"connection": self, "response": self.connection.getresponse()}
        else:
            responseCls = self.responseCls
            kwargs = {"connection": self, "response": self.connection.getresponse()}

        try:
            response = responseCls(**kwargs)
        finally:
            # Always reset the context after the request has completed
            self.reset_context()

        return response

    def morph_action_hook(self, action):
        """
        Here we strip any duplicated leading or traling slashes to
        prevent typos and other issues where some APIs don't correctly
        handle double slashes.

        Keep in mind that in some situations, "/" is a vallid path name
        so we have a module flag which disables this behavior
        (https://github.com/apache/libcloud/issues/1529).
        """
        if ALLOW_PATH_DOUBLE_SLASHES:
            # Special case to support scenarios where double slashes are
            # valid - e.g. for S3 paths - /bucket//path1/path2.txt
            return self.request_path + action

        url = urlparse.urljoin(self.request_path.lstrip("/").rstrip("/") + "/", action.lstrip("/"))

        if not url.startswith("/"):
            return "/" + url
        else:
            return url

    def add_default_params(self, params):
        """
        Adds default parameters (such as API key, version, etc.)
        to the passed `params`

        Should return a dictionary.
        """
        return params

    def add_default_headers(self, headers):
        """
        Adds default headers (such as Authorization, X-Foo-Bar)
        to the passed `headers`

        Should return a dictionary.
        """
        return headers

    def pre_connect_hook(self, params, headers):
        """
        A hook which is called before connecting to the remote server.
        This hook can perform a final manipulation on the params, headers and
        url parameters.

        :type params: ``dict``
        :param params: Request parameters.

        :type headers: ``dict``
        :param headers: Request headers.
        """
        return params, headers

    def encode_data(self, data):
        """
        Encode body data.

        Override in a provider's subclass.
        """
        return data

    def _add_cache_busting_to_params(self, params):
        """
        Add cache busting parameter to the query parameters of a GET request.

        Parameters are only added if "cache_busting" class attribute is set to
        True.

        Note: This should only be used with *naughty* providers which use
        excessive caching of responses.
        """
        cache_busting_value = binascii.hexlify(os.urandom(8)).decode("ascii")

        if isinstance(params, dict):
            params["cache-busting"] = cache_busting_value
        else:
            params.append(("cache-busting", cache_busting_value))

        return params


class PollingConnection(Connection):
    """
    Connection class which can also work with the async APIs.

    After initial requests, this class periodically polls for jobs status and
    waits until the job has finished.
    If job doesn't finish in timeout seconds, an Exception thrown.
    """

    poll_interval = 0.5
    timeout = 200
    request_method = "request"

    def async_request(
        self, action, params=None, data=None, headers=None, method="GET", context=None
    ):
        """
        Perform an 'async' request to the specified path. Keep in mind that
        this function is *blocking* and 'async' in this case means that the
        hit URL only returns a job ID which is the periodically polled until
        the job has completed.

        This function works like this:

        - Perform a request to the specified path. Response should contain a
          'job_id'.

        - Returned 'job_id' is then used to construct a URL which is used for
          retrieving job status. Constructed URL is then periodically polled
          until the response indicates that the job has completed or the
          timeout of 'self.timeout' seconds has been reached.

        :type action: ``str``
        :param action: A path

        :type params: ``dict``
        :param params: Optional mapping of additional parameters to send. If
            None, leave as an empty ``dict``.

        :type data: ``unicode``
        :param data: A body of data to send with the request.

        :type headers: ``dict``
        :param headers: Extra headers to add to the request
            None, leave as an empty ``dict``.

        :type method: ``str``
        :param method: An HTTP method such as "GET" or "POST".

        :type context: ``dict``
        :param context: Context dictionary which is passed to the functions
                        which construct initial and poll URL.

        :return: An :class:`Response` instance.
        :rtype: :class:`Response` instance
        """

        request = getattr(self, self.request_method)
        kwargs = self.get_request_kwargs(
            action=action,
            params=params,
            data=data,
            headers=headers,
            method=method,
            context=context,
        )
        response = request(**kwargs)
        kwargs = self.get_poll_request_kwargs(
            response=response, context=context, request_kwargs=kwargs
        )

        end = time.time() + self.timeout
        completed = False
        while time.time() < end and not completed:
            response = request(**kwargs)
            completed = self.has_completed(response=response)
            if not completed:
                time.sleep(self.poll_interval)

        if not completed:
            raise LibcloudError("Job did not complete in %s seconds" % (self.timeout))

        return response

    def get_request_kwargs(
        self, action, params=None, data=None, headers=None, method="GET", context=None
    ):
        """
        Arguments which are passed to the initial request() call inside
        async_request.
        """
        kwargs = {
            "action": action,
            "params": params,
            "data": data,
            "headers": headers,
            "method": method,
        }
        return kwargs

    def get_poll_request_kwargs(self, response, context, request_kwargs):
        """
        Return keyword arguments which are passed to the request() method when
        polling for the job status.

        :param response: Response object returned by poll request.
        :type response: :class:`HTTPResponse`

        :param request_kwargs: Kwargs previously used to initiate the
                                  poll request.
        :type response: ``dict``

        :return ``dict`` Keyword arguments
        """
        raise NotImplementedError("get_poll_request_kwargs not implemented")

    def has_completed(self, response):
        """
        Return job completion status.

        :param response: Response object returned by poll request.
        :type response: :class:`HTTPResponse`

        :return ``bool`` True if the job has completed, False otherwise.
        """
        raise NotImplementedError("has_completed not implemented")


class ConnectionKey(Connection):
    """
    Base connection class which accepts a single ``key`` argument.
    """

    def __init__(
        self,
        key,
        secure=True,
        host=None,
        port=None,
        url=None,
        timeout=None,
        proxy_url=None,
        backoff=None,
        retry_delay=None,
    ):
        """
        Initialize `user_id` and `key`; set `secure` to an ``int`` based on
        passed value.
        """
        super().__init__(
            secure=secure,
            host=host,
            port=port,
            url=url,
            timeout=timeout,
            proxy_url=proxy_url,
            backoff=backoff,
            retry_delay=retry_delay,
        )
        self.key = key


class CertificateConnection(Connection):
    """
    Base connection class which accepts a single ``cert_file`` argument.
    """

    def __init__(
        self,
        cert_file,
        secure=True,
        host=None,
        port=None,
        url=None,
        proxy_url=None,
        timeout=None,
        backoff=None,
        retry_delay=None,
    ):
        """
        Initialize `cert_file`; set `secure` to an ``int`` based on
        passed value.
        """
        super().__init__(
            secure=secure,
            host=host,
            port=port,
            url=url,
            timeout=timeout,
            backoff=backoff,
            retry_delay=retry_delay,
            proxy_url=proxy_url,
        )

        self.cert_file = cert_file


class KeyCertificateConnection(CertificateConnection):
    """
    Base connection class which accepts both ``key_file`` and ``cert_file``
    argument.
    """

    key_file = None

    def __init__(
        self,
        key_file,
        cert_file,
        secure=True,
        host=None,
        port=None,
        url=None,
        proxy_url=None,
        timeout=None,
        backoff=None,
        retry_delay=None,
        ca_cert=None,
    ):
        """
        Initialize `cert_file`; set `secure` to an ``int`` based on
        passed value.
        """
        super().__init__(
            cert_file,
            secure=secure,
            host=host,
            port=port,
            url=url,
            timeout=timeout,
            backoff=backoff,
            retry_delay=retry_delay,
            proxy_url=proxy_url,
        )

        self.key_file = key_file


class ConnectionUserAndKey(ConnectionKey):
    """
    Base connection class which accepts a ``user_id`` and ``key`` argument.
    """

    user_id = None  # type: int

    def __init__(
        self,
        user_id,
        key,
        secure=True,
        host=None,
        port=None,
        url=None,
        timeout=None,
        proxy_url=None,
        backoff=None,
        retry_delay=None,
    ):
        super().__init__(
            key,
            secure=secure,
            host=host,
            port=port,
            url=url,
            timeout=timeout,
            backoff=backoff,
            retry_delay=retry_delay,
            proxy_url=proxy_url,
        )
        self.user_id = user_id


class BaseDriver:
    """
    Base driver class from which other classes can inherit from.
    """

    connectionCls = ConnectionKey  # type: Type[Connection]

    def __init__(
        self,
        key,
        secret=None,
        secure=True,
        host=None,
        port=None,
        api_version=None,
        region=None,
        **kwargs,
    ):
        """
        :param    key:    API key or username to be 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    api_version: Optional API version. Only used by drivers
                                 which support multiple API versions.
        :type     api_version: ``str``

        :param region: Optional driver region. Only used by drivers which
                       support multiple regions.
        :type region: ``str``

        :rtype: ``None``
        """

        self.key = key
        self.secret = secret
        self.secure = secure
        self.api_version = api_version
        self.region = region

        conn_kwargs = self._ex_connection_class_kwargs()
        conn_kwargs.update(
            {
                "timeout": kwargs.pop("timeout", None),
                "retry_delay": kwargs.pop("retry_delay", None),
                "backoff": kwargs.pop("backoff", None),
                "proxy_url": kwargs.pop("proxy_url", None),
            }
        )

        args = [self.key]

        if self.secret is not None:
            args.append(self.secret)

        args.append(secure)

        host = conn_kwargs.pop("host", None) or host

        if host is not None:
            args.append(host)

        if port is not None:
            args.append(port)

        self.connection = self.connectionCls(*args, **conn_kwargs)
        self.connection.driver = self
        self.connection.connect()

    def _ex_connection_class_kwargs(self):
        """
        Return extra connection keyword arguments which are passed to the
        Connection class constructor.
        """
        return {}
