# coding: utf-8
# Copyright (c) 2016 Fabian Barkhau <f483@storj.io>
# License: MIT (see LICENSE file)


import re
import time
import json
import requests
from requests.auth import HTTPBasicAuth
from collections import defaultdict
from six.moves.urllib.parse import urljoin
from . import auth


method_cumulative_calltime = defaultdict(float)


class JsonRpcCallFailed(Exception):

    def __init__(self, payload, response):
        msg = "Rpc call failed! {0} -> {1}".format(payload, response)
        super(JsonRpcCallFailed, self).__init__(msg)


def _jsonrpc_call(url, method, params={}, verify_ssl_cert=True,
                  username=None, password=None):
    payload = {"method": method, "params": params, "jsonrpc": "2.0", "id": 0}
    kwargs = {
        "url": url,
        "headers": {'content-type': 'application/json'},
        "data": json.dumps(payload),
        "verify": verify_ssl_cert,
    }
    if username and password:
        kwargs["auth"] = HTTPBasicAuth(username, password)

    global method_cumulative_calltime
    begin = time.time()
    response = requests.post(**kwargs).json()
    method_cumulative_calltime[method] += (time.time() - begin)

    if "result" not in response:
        raise JsonRpcCallFailed(payload, response)
    return response["result"]


def _auth_jsonrpc_call(url, method, params={}, verify_ssl_cert=True,
                       privkey=None, username=None, password=None):

    if privkey:
        params = auth.sign_json(params, privkey)

    result = _jsonrpc_call(url, method, params=params, username=username,
                           password=password, verify_ssl_cert=verify_ssl_cert)

    if privkey:
        auth.verify_json(result)

    return result


class JsonRpc(object):

    def __init__(self, url, privkey=None, verify_ssl_cert=True,
                 username=None, password=None):
        self.url = url
        self.privkey = privkey
        self.username = username
        self.password = password
        self.verify_ssl_cert = verify_ssl_cert

    def __getattribute__(self, name):
        props = ["url", "privkey", "verify_ssl_cert", "username", "password"]
        auth_methods = ["mph_request", "mph_deposit", "mph_sync", "test_auth"]

        if name in props:
            return object.__getattribute__(self, name)

        def wrapper(**kwargs):
            privkey = self.privkey if name in auth_methods else None
            return _auth_jsonrpc_call(
                url=self.url,
                method=name,
                params=kwargs,
                privkey=privkey,
                verify_ssl_cert=self.verify_ssl_cert,
                username=self.username,
                password=self.password
            )
        return wrapper

@@ -101,18 +101,8 @@
 )%0A%0A%0A
-import re%0A
 impo
@@ -217,51 +217,8 @@
 ict%0A
-from six.moves.urllib.parse import urljoin%0A
 from
@@ -493,17 +493,16 @@
 )%0A%0A%0Adef 
-_
 jsonrpc_
@@ -544,33 +544,32 @@
 _ssl_cert=True,%0A
- 
                 
@@ -1231,17 +1231,16 @@
 %5D%0A%0A%0Adef 
-_
 auth_jso
@@ -1287,33 +1287,32 @@
 _ssl_cert=True,%0A
- 
                 
@@ -1442,17 +1442,16 @@
 esult = 
-_
 jsonrpc_
@@ -1494,33 +1494,32 @@
 rname=username,%0A
- 
                 
@@ -2352,17 +2352,16 @@
  return 
-_
 auth_jso

make core jsonrpc method part of lib