import log
logger = log.get(__name__)

import starter as _starter
from functools import wraps
import inspect

# PEERS 
def monitorPeers(kind, name, endpoint, cb):
    _starter.registry.subscribe(kind, [name, endpoint], cb)

def getPeers(kind, name, endpoint):
    return _starter.registry.get(kind, [name, endpoint])

def getRandomPeer(kind, name, endpoint):
    peers = getPeers(kind, name, endpoint)
    return _starter.randomFromDict(peers)

def request(kind, name, endpoint):
    return _starter.makeRequest(kind, name, endpoint)

# DATABASES 
def monitorDatabases(name, cb):
    _starter.monitorNatives('database', name, cb)

def getDatabases(name):
    return _starter.getNatives('database', name)

def getDatabase(name):
    return _starter.getNative('database', name)

def getDatabaseClient(name):
    return _starter.getNativeClient('database', name)

# QUEUES 
def monitorQueues(name, cb):
    _starter.monitorNatives('queue', name, cb)

def getQueues(name):
    return _starter.getNatives('queue', name)

def getQueue(name):
    return _starter.getNative('queue', name)

def getQueueClient(name):
    return _starter.getNativeClient('queue', name)

# TRACING
def instrument(method, binary_annotations=None):
    return _starter.instrument(method, binary_annotations)

def instrument_func(**instArgs):
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            mod = inspect.getmodule(f)
            binary_annotations = instArgs.get('binary_annotations', {})
            binary_annotations['source.path'] = mod.__file__
            binary_annotations['source.func'] = f.__name__
            binary_annotations['source.module'] = mod.__name__
            method = instArgs.get('name')
            if not method:
                method = 'func-' + f.__name__

            with instrument(method, binary_annotations):
                return f(*args, **kwargs)
        return wrapper
    return decorator

# FRAMEWORKS
def setupFlask(app):
    return _starter.setupFlask(app)