import inspect
from functools import partial

from arq import cron
from intranet.domenator.src.worker import periodic_tasks
from intranet.domenator.src.worker import tasks

from intranet.domenator.src.db.engine import get_engine_config, db
from intranet.domenator.src.redis import get_redis_settings
from intranet.domenator.src.settings import config
# from intranet.domenator.src.logbroker import get_client, LogbrokerClient


async def startup(ctx):
    engine_kwargs = get_engine_config()
    bind = engine_kwargs['dsn']
    echo = engine_kwargs['echo']
    ssl = engine_kwargs['ssl']
    kwargs = engine_kwargs['kwargs']
    await db.set_bind(bind=bind, echo=echo, ssl=ssl, **kwargs)

    # no need because task not working
    # ctx['logbroker'] = get_client()


async def shutdown(ctx):
    await db.pop_bind().close()
    # logbroker: LogbrokerClient = ctx['logbroker']
    # logbroker.shutdown()


def check_is_job_of_type(is_cron: bool, task):
    arq_settings = getattr(task, 'arq_config', None)
    if not inspect.isfunction(task) or arq_settings is None:
        return False
    if not is_cron:
        return True
    return arq_settings['is_cron'] and arq_settings.get('predicate', True)


def get_jobs(is_cron: bool):
    validate_job = partial(check_is_job_of_type, is_cron)
    jobs_from_tasks = inspect.getmembers(tasks, validate_job)
    jobs_from_periodic_tasks = inspect.getmembers(periodic_tasks, validate_job)
    return [function for name, function in jobs_from_tasks + jobs_from_periodic_tasks]


def get_cron_jobs():
    jobs = get_jobs(is_cron=True)
    return [cron(job, **job.arq_config['cron_kwargs']) for job in jobs]


class WorkerSettings:
    on_startup = startup
    on_shutdown = shutdown
    redis_settings = get_redis_settings()
    functions = get_jobs(is_cron=False)
    cron_jobs = get_cron_jobs()
    max_tries = 4
    queue_name = config.redis_queue_name
