# 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 time
import hashlib
from typing import List

from libcloud.http import LibcloudConnection
from libcloud.utils.py3 import httplib
from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import InvalidCredsError
from libcloud.utils.connection import get_response_object

try:
    import simplejson as json
except ImportError:
    import json  # type: ignore


__all__ = ["OvhResponse", "OvhConnection"]

API_HOST = "api.ovh.com"
API_ROOT = "/1.0"
# From https://us.ovhcloud.com/about/company/data-centers
LOCATIONS = {
    "BHS1": {"id": "BHS1", "name": "Beauharnois, Quebec 1", "country": "CA"},
    "BHS2": {"id": "BHS2", "name": "Beauharnois, Quebec 2", "country": "CA"},
    "BHS3": {"id": "BHS3", "name": "Beauharnois, Quebec 3", "country": "CA"},
    "BHS4": {"id": "BHS4", "name": "Beauharnois, Quebec 4", "country": "CA"},
    "BHS5": {"id": "BHS5", "name": "Beauharnois, Quebec 5", "country": "CA"},
    "BHS6": {"id": "BHS6", "name": "Beauharnois, Quebec 6", "country": "CA"},
    "DC1": {"id": "DC1", "name": "Paris DC1", "country": "FR"},
    "FRA1": {"id": "FRA1", "name": "Frankfurt 1", "country": "DE"},
    "GRA1": {"id": "GRA1", "name": "Gravelines 1", "country": "FR"},
    "GRA2": {"id": "GRA2", "name": "Gravelines 2", "country": "FR"},
    "GSW": {"id": "GSW", "name": "Paris GSW", "country": "FR"},
    "HIL1": {"id": "HIL1", "name": "Hillsboro, Oregon 1", "country": "US"},
    "LON1": {"id": "LON1", "name": "London 1", "country": "UK"},
    "P19": {"id": "P19", "name": "Paris P19", "country": "FR"},
    "RBX1": {"id": "RBX1", "name": "Roubaix 1", "country": "FR"},
    "RBX2": {"id": "RBX2", "name": "Roubaix 2", "country": "FR"},
    "RBX3": {"id": "RBX3", "name": "Roubaix 3", "country": "FR"},
    "RBX4": {"id": "RBX4", "name": "Roubaix 4", "country": "FR"},
    "RBX5": {"id": "RBX5", "name": "Roubaix 5", "country": "FR"},
    "RBX6": {"id": "RBX6", "name": "Roubaix 6", "country": "FR"},
    "RBX7": {"id": "RBX7", "name": "Roubaix 7", "country": "FR"},
    "SBG1": {"id": "SBG1", "name": "Strasbourg 1", "country": "FR"},
    "SBG2": {"id": "SBG2", "name": "Strasbourg 2", "country": "FR"},
    "SBG3": {"id": "SBG3", "name": "Strasbourg 3", "country": "FR"},
    "SGP1": {"id": "SGP1", "name": "Singapore 1", "country": "SG"},
    "SYD1": {"id": "SYD1", "name": "Sydney 1", "country": "AU"},
    "VIN1": {"id": "VIN1", "name": "Vint Hill, Virginia 1", "country": "US"},
    "WAW1": {"id": "WAW1", "name": "Warsaw 1", "country": "PL"},
}
DEFAULT_ACCESS_RULES = [
    {"method": "GET", "path": "/*"},
    {"method": "POST", "path": "/*"},
    {"method": "PUT", "path": "/*"},
    {"method": "DELETE", "path": "/*"},
]


class OvhException(Exception):
    pass


class OvhResponse(JsonResponse):
    def parse_error(self):
        response = super().parse_body()
        response = response or {}

        if response.get("errorCode", None) == "INVALID_SIGNATURE":
            raise InvalidCredsError(
                "Signature validation failed, probably " "using invalid credentials"
            )

        return self.body


class OvhConnection(ConnectionUserAndKey):
    """
    A connection to the Ovh API

    Wraps SSL connections to the Ovh API, automagically injecting the
    parameters that the API needs for each request.
    """

    host = API_HOST
    request_path = API_ROOT
    responseCls = OvhResponse
    timestamp = None
    ua = []  # type: List[str]
    LOCATIONS = LOCATIONS
    _timedelta = None

    allow_insecure = True

    def __init__(self, user_id, *args, **kwargs):
        region = kwargs.pop("region", "")
        if region:
            self.host = ("{}.{}".format(region, API_HOST)).lstrip(".")
        else:
            self.host = API_HOST
        self.consumer_key = kwargs.pop("ex_consumer_key", None)
        if self.consumer_key is None:
            consumer_key_json = self.request_consumer_key(user_id)
            msg = (
                "Your consumer key isn't validated, "
                "go to '%(validationUrl)s' for valid it. After instantiate "
                "your driver with \"ex_consumer_key='%(consumerKey)s'\"." % consumer_key_json
            )
            raise OvhException(msg)
        super().__init__(user_id, *args, **kwargs)

    def request_consumer_key(self, user_id):
        action = self.request_path + "/auth/credential"
        data = json.dumps({"accessRules": DEFAULT_ACCESS_RULES, "redirection": "http://ovh.com"})
        headers = {
            "Content-Type": "application/json",
            "X-Ovh-Application": user_id,
        }
        httpcon = LibcloudConnection(host=self.host, port=443)

        try:
            httpcon.request(method="POST", url=action, body=data, headers=headers)
        except Exception as e:
            handle_and_rethrow_user_friendly_invalid_region_error(host=self.host, e=e)

        response = OvhResponse(httpcon.getresponse(), httpcon)

        if response.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError()

        json_response = response.parse_body()
        httpcon.close()
        return json_response

    def get_timestamp(self):
        if not self._timedelta:
            url = "https://{}{}/auth/time".format(self.host, API_ROOT)
            response = get_response_object(url=url, method="GET", headers={})
            if not response or not response.body:
                raise Exception("Failed to get current time from Ovh API")

            timestamp = int(response.body)
            self._timedelta = timestamp - int(time.time())
        return int(time.time()) + self._timedelta

    def make_signature(self, method, action, params, data, timestamp):
        full_url = "https://{}{}".format(self.host, action)
        if params:
            full_url += "?"
            for key, value in params.items():
                full_url += "{}={}&".format(key, value)
            full_url = full_url[:-1]
        sha1 = hashlib.sha1()
        base_signature = "+".join(
            [
                self.key,
                self.consumer_key,
                method.upper(),
                full_url,
                data if data else "",
                str(timestamp),
            ]
        )
        sha1.update(base_signature.encode())
        signature = "$1$" + sha1.hexdigest()
        return signature

    def add_default_params(self, params):
        return params

    def add_default_headers(self, headers):
        headers.update(
            {
                "X-Ovh-Application": self.user_id,
                "X-Ovh-Consumer": self.consumer_key,
                "Content-type": "application/json",
            }
        )
        return headers

    def request(self, action, params=None, data=None, headers=None, method="GET", raw=False):
        data = json.dumps(data) if data else None
        timestamp = self.get_timestamp()
        signature = self.make_signature(method, action, params, data, timestamp)
        headers = headers or {}
        headers.update({"X-Ovh-Timestamp": timestamp, "X-Ovh-Signature": signature})

        try:
            return super().request(
                action,
                params=params,
                data=data,
                headers=headers,
                method=method,
                raw=raw,
            )
        except Exception as e:
            handle_and_rethrow_user_friendly_invalid_region_error(host=self.host, e=e)


def handle_and_rethrow_user_friendly_invalid_region_error(host, e):
    """
    Utility method which throws a more user-friendly error in case "name or
    service not known" error is received when sending a request.

    In most cases this error indicates user passed invalid ``region`` argument
    to the driver constructor.
    """
    msg = str(e).lower()

    error_messages_to_throw = [
        "name or service not known",
        "nodename nor servname provided, or not known",
        "getaddrinfo failed",
    ]

    if any([value for value in error_messages_to_throw if value in msg]):
        raise ValueError(
            'Received "name or service not known" error '
            "when sending a request. This likely "
            "indicates invalid region argument was "
            "passed to the driver constructor."
            "Used host: %s. Original error: %s" % (host, str(e))
        )

    raise e
