import logging
import datetime

import saas.tools.ssm.modules.yaml_config as yaml_config

import saas.library.persqueue.common.python.installations as lb_installations
import saas.library.persqueue.configuration.python.global_log as global_log
import saas.library.persqueue.configuration.python.service as service_configuration
import saas.library.persqueue.configuration.python.namespace as namespace_configuration
import saas.library.persqueue.configuration.proto.types_pb2 as configuration_types

from saas.library.python.token_store import PersistentTokenStore
from saas.library.python.sandbox import SandboxApi


def init_logs(logfile=None, loglevel=logging.INFO):
    global_log.init(
        logfile if logfile else 'cerr',
        loglevel
    )


def create_lb_service_config(service_name, service_ctype, config_path):
    lb_resources_config = yaml_config.read_configuration(config_path)

    namespace = lb_resources_config['service_namespace']
    ns = namespace_configuration.NamespaceManager(namespace)

    logbroker = configuration_types.ELogbrokerName.Value(lb_resources_config['logbroker_cluster'])
    logbroker_mirror = configuration_types.ELogbrokerName.Value(lb_resources_config['logbroker_mirror_cluster']) \
        if lb_resources_config.get('logbroker_mirror_cluster') \
        else None

    data_centers = []
    for dc in lb_resources_config['data_centers'].split(','):
        data_centers.append(configuration_types.EDataCenter.Value(dc))

    service_config = ns.create_service_config(
        service_name,
        service_ctype,
        logbroker=logbroker,
        logbroker_mirror=logbroker_mirror,
        data_centers=data_centers,
        yt_delivery_clusters=lb_resources_config['yt_delivery_clusters'].split(',')
    )
    return service_config, namespace


def create_lb_resources(service_name, service_ctype, tvm_write, tvm_read, config_path='conf/logbroker.conf'):
    service_config, namespace = create_lb_service_config(service_name, service_ctype, config_path)
    service = service_configuration.ServiceConfiguration(
        namespace,
        service_name,
        service_ctype,
        service_config,
        no_remove=True
    )
    service.create(write_tvm_values=tvm_write, read_tvm_values=tvm_read)
    service.apply()
    return service_config


def create_sb_scheduler(service_name, service_ctype, service_config, fm_host):
    description = '{} {}'.format(service_name, service_ctype)
    start_time = datetime.datetime.utcnow() + datetime.timedelta(seconds=30)
    task_type = 'UPLOAD_LOGFELLER_DATA_2'
    max_schedulers_limit = 500

    sb = SandboxApi(PersistentTokenStore.get_token_from_store_env_or_file('sandbox'))
    schedulers = sb.find_schedulers(task_type, limit=max_schedulers_limit)

    scheduler_id = None
    for scheduler in schedulers:
        if scheduler.last_task and scheduler.last_task.description == description:
            if scheduler_id is not None:
                raise Exception('Found two schedulers with the same description="{}" ids: {}, {}'.format(
                    description, scheduler_id, scheduler.id
                ))
            scheduler_id = scheduler.id

    scheduler_params = {
        'sequential_run': True,
        'start_time': start_time.isoformat(),
        'repetition': {
            'interval': 5 * 60,
        },
        'retry': {
            'ignore': True,
        }
    }
    task_params = {
        'service': service_name,
        'ctype': service_ctype,
        'fm_host': fm_host,
        'tables_per_shard': 5,
        'lb_delivery_path': '{delivery_path}/{topic_path}'.format(
            delivery_path=lb_installations.get_yt_delivery_path(service_config.Logbroker),
            topic_path=service_config.TopicsPath
        )
    }
    task_notifications = [{
        'statuses': ['BREAK', 'FAILURE'],
        'recipients': ['saas-lb-backups-fail'],
        'transport': 'email'
    }]

    if scheduler_id is None:
        scheduler = sb.add_scheduler(
            task_type=task_type,
            owner='SAAS-ROBOT',
            scheduler_params=scheduler_params,
            task_params=task_params,
            description=description,
            task_notifications=task_notifications,
            task_priority='SERVICE:HIGH'
        )
        scheduler.start()

        logging.info('Created a new sandbox scheduler with id=%s', scheduler.id)
        return scheduler.id
    else:
        sb.update_scheduler(
            scheduler_id=scheduler_id,
            scheduler_params=scheduler_params,
            task_params=task_params,
            description=description,
            task_notifications=task_notifications
        )

        logging.info('Updated existing sandbox scheduler with id=%s', scheduler_id)
        return scheduler_id
