#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from optparse import OptionParser

import yenv
from logbroker_client.logbroker.client import LogbrokerMeta
from logbroker_client.logbroker_app import configure
from logbroker_client.consumers.simple.emitter import PartitionsCountEmitter
from logbroker_client.utils import importobj
from logbroker_client.monitoring import *

log = logging.getLogger('logbroker_client.monitoring')

DEFAULT_CONFIG_PATH = '/etc/yandex/logbroker-client/'

DEFAULT_MAX_CLIENT_QUEUE_SIZE = 60000


def get_configured_offsets_info(config):
    emitter_args = config['emitter'].get('args', {})
    emitter = PartitionsCountEmitter(**emitter_args)
    meta = LogbrokerMeta(emitter.balancer_host, emitter.client)

    partitions = []
    for ident in emitter.idents:
        ident_partitions = meta.show_parts(ident=ident)
        partitions.extend(ident_partitions)
    filtered_topics = emitter.filter_topics(partitions)
    return meta.get_offsets_info(emitter.client, filtered_topics, emitter.data_port, dc=emitter.dc)


def instantiate_handler(config):
    handler_conf = config['workers']['args']['handler']
    handler_cls = importobj(handler_conf.get('class'))
    handler_args = handler_conf.get('args')
    return handler_cls(**handler_args)


def check_client(service, config):
    policy = config.get('policy', {})

    with MonitoringState(service) as state:
        handler = instantiate_handler(config)
        finalize, code, message = handler.monitor(policy, state)
        if finalize:
            return code, message

    try:
        offsets_info = get_configured_offsets_info(config)
    except Exception as e:
        log.error('Failed to get queue size', exc_info=e)
        return MONITORING_STATUS_CRIT, 'failed to get queue size'

    max_queue_size = policy.get('max_client_queue_size', DEFAULT_MAX_CLIENT_QUEUE_SIZE)
    queue_size = sum(info['lag'] for info in offsets_info)
    if queue_size > max_queue_size:
        return MONITORING_STATUS_CRIT, 'queue size is %s' % queue_size

    return MONITORING_STATUS_OK, 'OK'


if __name__ == '__main__':
    optparser = OptionParser()

    optparser.add_option("-s", "--service", dest="service", help="name of service")
    optparser.add_option("-p", "--path", dest="path", help="path to configs")
    optparser.add_option("-c", "--config", dest="config", help="path to config")  # for debug usage

    options, args = optparser.parse_args()

    config_file = None

    if not options.service:
        optparser.error("--service option is required")
    elif options.config:
        config_file = options.config
    elif options.service:
        config_path = DEFAULT_CONFIG_PATH
        if options.path:
            config_path = options.path
        config_file = config_path + options.service + '/' + yenv.type + ".json"

    config = configure(config_file)

    code, message = check_client(options.service, config)
    log.debug('%s monitoring result: %s;%s', options.service, code, message)
    print '%d;%s' % (code, message)
