# -*- coding: utf-8 -*-
import json
import logging
import requests
from base64 import b64encode

log = logging.getLogger(__name__)


class Multichain():
    __id_count = 0

    def __init__(self,
                 rpcuser,
                 rpcpasswd,
                 rpchost,
                 rpcport,
                 chainname,
                 rpc_call=None
                 ):
        self.__rpcuser = rpcuser
        self.__rpcpasswd = rpcpasswd
        self.__rpchost = rpchost
        self.__rpcport = rpcport
        self.__chainname = chainname
        self.__auth_header = ' '.join(
            ['Basic', b64encode(':'.join([rpcuser, rpcpasswd]).encode()).decode()]
        )
        self.__headers = {'Host': self.__rpchost,
                          'User-Agent': 'Multichain python binding',
                          'Authorization': self.__auth_header,
                          'Content-type': 'application/json'
                          }
        self.__rpc_call = rpc_call

    def __getattr__(self, name):
        if name.startswith('__') and name.endswith('__'):
            # Python internal stuff
            raise AttributeError
        if self.__rpc_call is not None:
            name = "%s.%s" % (self.__rpc_call, name)
        return Multichain(self.__rpcuser,
                          self.__rpcpasswd,
                          self.__rpchost,
                          self.__rpcport,
                          self.__chainname,
                          name)

    def __call__(self, *args):
        Multichain.__id_count += 1
        postdata = {'chain_name': self.__chainname,
                    'version': '2.0',
                    'params': args,
                    'method': self.__rpc_call,
                    'id': Multichain.__id_count}
        protocol = 'https' if int(self.__rpcport) == 443 else 'http'
        url = '{0}://{1}:{2}'.format(protocol, self.__rpchost, self.__rpcport)
        encoded = json.dumps(postdata)
        log.info("Request: %s" % encoded)
        r = requests.post(url, data=encoded, headers=self.__headers)
        if r.status_code == 200:
            log.info("Response: %s" % r.json())
            return r.json()['result']
        else:
            log.error("Error! Status code: %s" % r.status_code)
            log.error("Text: %s" % r.text)
            log.error("Json: %s" % r.json())
            return r.json()
