#### PATTERN | WEB | OAUTH #########################################################################
# -*- coding: utf-8 -*-
# Copyright (c) 2010 University of Antwerp, Belgium
# Author: Tom De Smedt <tom@organisms.be>
# License: BSD (see LICENSE.txt for details).
# http://www.clips.ua.ac.be/pages/pattern

####################################################################################################
# Naive OAuth implementation for pattern.web.Yahoo and Yahoo! BOSS v2.

from __future__ import unicode_literals
from __future__ import division

from builtins import str, bytes, dict, int
from builtins import map, zip, filter
from builtins import object, range

try:
    # Python 3
    from urllib.parse import urlencode
    from urllib.parse import quote as urlquote
except ImportError:
    from urllib import urlencode
    from urllib import quote as urlquote

import hmac
import time
import random
import base64

try:
    from hashlib import sha1
    from hashlib import md5
except:
    import sha as sha1
    import md5
    md5 = md5.new

_diacritics = {
    "a": ("á", "ä", "â", "à", "å"),
    "e": ("é", "ë", "ê", "è"),
    "i": ("í", "ï", "î", "ì"),
    "o": ("ó", "ö", "ô", "ò", "ō", "ø"),
    "u": ("ú", "ü", "û", "ù", "ů"),
    "y": ("ý", "ÿ", "ý"),
    "s": ("š",),
    "c": ("ç", "č"),
    "n": ("ñ",),
    "z": ("ž",)
}

####################################################################################################


def HMAC_SHA1(key, text):
    return hmac.new(key.encode("utf-8"), text.encode("utf-8"), sha1).digest()


def nonce():
    return md5(str(time.time()).encode("utf-8") + str(random.random()).encode("utf-8")).hexdigest()


def timestamp():
    return int(time.time())


def escape(string):
    return urlquote(string, safe=b"~")


def utf8(string):
    return isinstance(string, str) and string.encode("utf-8") or str(string)


def normalize(string):
    # Normalize accents (é => e) for services that have problems with utf-8
    # (used to be the case with Yahoo BOSS but this appears to be fixed now).
    string = utf8(string)
    for k, v in _diacritics.items():
        for v in v:
            string = string.replace(v, k)
    return string


def base(url, data={}, method="GET"):
    # Signature base string: http://tools.ietf.org/html/rfc5849#section-3.4.1
    base = escape(utf8(method.upper())) + "&"
    base += escape(utf8(url.rstrip("?"))) + "&"
    base += escape(utf8("&".join(["%s=%s" % (
            escape(utf8(k)),
            escape(utf8(v))) for k, v in sorted(data.items())])))
    return base


def sign(url, data={}, method="GET", secret="", token="", hash=HMAC_SHA1):
    # HMAC-SHA1 signature algorithm: http://tools.ietf.org/html/rfc5849#section-3.4.2
    signature = escape(utf8(secret)) + "&" + escape(utf8(token))
    signature = hash(signature, base(url, data, method))
    signature = base64.b64encode(signature)
    return signature.decode("utf-8")

#CONSUMER_KEY = ""
#CONSUMER_SECRET = ""
#
#q = "cats"
#url = "http://yboss.yahooapis.com/ysearch/web"
#data = {
#    "q": normalize(q),
#    "start": 0,
#    "count": 50,
#    "format": "json",
#    "oauth_version": "1.0",
#    "oauth_nonce": nonce(),
#    "oauth_timestamp": timestamp(),
#    "oauth_consumer_key": CONSUMER_KEY,
#    "oauth_signature_method": "HMAC-SHA1"
#}
#data["oauth_signature"] = sign(url, data, secret=CONSUMER_SECRET)
#data = dict((k, utf8(v)) for k, v in data.items())
#
#print(url + "?" + urlencode(data))
