# 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 random
import string
import hashlib

from libcloud.utils.py3 import httplib, urlencode, basestring
from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import ProviderError, InvalidCredsError

SALT_CHARACTERS = string.ascii_letters + string.digits


class NFSNException(ProviderError):
    def __init__(self, value, http_code, code, driver=None):
        self.code = code
        super().__init__(value, http_code, driver)


class NFSNResponse(JsonResponse):
    def parse_error(self):
        if self.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError("Invalid provider credentials")

        body = self.parse_body()

        if isinstance(body, basestring):
            return body + " (HTTP Code: %d)" % self.status

        error = body.get("error", None)
        debug = body.get("debug", None)
        # If we only have one of "error" or "debug", use the one that we have.
        # If we have both, use both, with a space character in between them.
        value = "No message specified"
        if error is not None:
            value = error
        if debug is not None:
            value = debug
        if error is not None and value is not None:
            value = error + " " + value
        value = value + " (HTTP Code: %d)" % self.status

        return value


class NFSNConnection(ConnectionUserAndKey):
    host = "api.nearlyfreespeech.net"
    responseCls = NFSNResponse
    allow_insecure = False

    def _header(self, action, data):
        """Build the contents of the X-NFSN-Authentication HTTP header. See
        https://members.nearlyfreespeech.net/wiki/API/Introduction for
        more explanation."""
        login = self.user_id
        timestamp = self._timestamp()
        salt = self._salt()
        api_key = self.key
        data = urlencode(data)
        data_hash = hashlib.sha1(data.encode("utf-8")).hexdigest()

        string = ";".join((login, timestamp, salt, api_key, action, data_hash))
        string_hash = hashlib.sha1(string.encode("utf-8")).hexdigest()

        return ";".join((login, timestamp, salt, string_hash))

    def request(self, action, params=None, data="", headers=None, method="GET"):
        """Add the X-NFSN-Authentication header to an HTTP request."""
        if not headers:
            headers = {}
        if not params:
            params = {}
        header = self._header(action, data)

        headers["X-NFSN-Authentication"] = header
        if method == "POST":
            headers["Content-Type"] = "application/x-www-form-urlencoded"

        return ConnectionUserAndKey.request(self, action, params, data, headers, method)

    def encode_data(self, data):
        """NFSN expects the body to be regular key-value pairs that are not
        JSON-encoded."""
        if data:
            data = urlencode(data)
        return data

    def _salt(self):
        """Return a 16-character alphanumeric string."""
        r = random.SystemRandom()
        return "".join(r.choice(SALT_CHARACTERS) for _ in range(16))

    def _timestamp(self):
        """Return the current number of seconds since the Unix epoch,
        as a string."""
        return str(int(time.time()))
