import logging
import json
import time
from TDhelper.network.http.REST_HTTP import GET
from TDhelper.generic.dynamic.base.Meta import dynamic_creator
from TDhelper.network.rpc.Core.struct import RPC_SERVICE
from TDhelper.Decorators.log import logging,logging_setup
from TDhelper.Decorators.performance import performance
from macpath import split

performance.on_off(True)

class client():
    __TOKEN_KEY__="api-token"
    __TOKEN__=""
    __LOGGER__=logging
    
    @performance.performance_testing
    def __init__(self,uri="",token="",services=None,token_key=None,logger:dict=None):
        if logger:
            self.__LOGGER__.basicConfig(level=logging.INFO)
            self.__LOGGER__.config.dictConfig(logger)
        self.__TOKEN_KEY__= token_key if token_key else self.__TOKEN_KEY__
        self.__TOKEN__=token
        header={
            self.__TOKEN_KEY__:self.__TOKEN__
        }
        if services:
            uri=uri.rstrip("/")
            uri+="?key="+str.split(services,",")
        self.__context__=self.__get_conf__(uri,header)
        if self.__context__:
            self.__dict__["__srv_struct__"]={}
            for k,v in self.__context__.items():
                self.__dict__["__srv_struct__"][k]=type(k,(RPC_SERVICE,),{}).create_by_cnf(v,self.__TOKEN_KEY__)
                methods=[kv for kv in v['methods'].keys()]
                self.__dict__[k]=type(k,(dynamic_creator,),{"__dynamic_methods__":methods,"__hook_method__":self.__call__})()
        else:
            self.__LOGGER__.error("not found rpc method.")
            raise Exception("not found rpc method.")
        super(client,self).__init__()
        
    @performance.performance_testing
    def __call__(self,service_name,fun_name,*args,**kwargs):
        remote_func_name= ("".join([service_name,'.',fun_name]))
        if service_name in self.__srv_struct__:
            if hasattr(self.__srv_struct__[service_name],'methods'):
                if fun_name in self.__srv_struct__[service_name].methods:
                    try:
                        start= time.clock_gettime(0)
                        result= self.__srv_struct__[service_name].__remote_call__(fun_name,*args,**kwargs)
                        end= time.clock_gettime(0)
                        self.__LOGGER__.info("call %s, time consuming %f(s)" % (remote_func_name,(end-start)))
                        return result
                    except Exception as e:
                        self.__LOGGER__.error(e)
                else:
                    self.__LOGGER__.error("in service(%s) not found method(%s)",(service_name,fun_name))
            else:
                self.__LOGGER__.error("service obj not found key(methods).")
        else:
            self.__LOGGER__.error('not found service(%s).'%service_name)
        return {"state": -1, "msg": {}}
        
    def __get_conf__(self,uri,header={}):
        state,body=GET(uri,http_headers=header,time_out=5,charset="utf-8")
        if state==200:
            body=json.loads(body)
            if body["state"]==200:
                return body["msg"]
            else:
                return {}
        return {}