# -*- coding: utf-8 -*-
import sentry_sdk
import logging
import flask
import traceback

from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
from errorboosterclient.sentry import ErrorBoosterTransport
from errorboosterclient.logbroker import LogbrokerClient


LOGBROKER_TOPIC_PATH = "saas/errorbooster/infra-saas"
DEFAULT_INTEGRATIONS = [
    LoggingIntegration(
        level=logging.WARNING,  # Capture warning and above as breadcrumbs
        event_level=logging.WARNING),
    FlaskIntegration()
]


class ErrorBooster(object):
    """
    Errorbooster helpers class
    More information about Errorbooster is here https://wiki.yandex-team.ru/error-booster/
    """
    def __init__(self, project_name, topic_path=LOGBROKER_TOPIC_PATH,
                 environment="production", integrations=DEFAULT_INTEGRATIONS, release="0.0.1"):
        """
        Initial method to configure Errorbooster for your application
        :param project_name: type sting
        :param topic_path: type string
        :param environment: type string
        :param integrations: type list of "custom integrations"
        """
        self.project = project_name
        self.topic_path = topic_path
        self.environment = environment
        self.integrations = integrations
        self.release = release
        self.init()

    def send_me(self, event):
        """
        Main Logbroker transport method
        :param event: type dict
        """
        with LogbrokerClient() as logbroker:
            with logbroker.get_producer(source="test_source", topic=self.topic_path) as producer:
                logging.debug("This event will be send to errorbooster: %s", event)
                log_level = logging.getLogger().getEffectiveLevel()
                try:
                    logging.getLogger().setLevel(logging.INFO)
                    producer.write(event)
                finally:
                    logging.getLogger().setLevel(log_level)

    def init(self):
        """
        Main method to configure Errorbooster using variables from __init__
        """
        sentry_sdk.init(
            transport=ErrorBoosterTransport(project=self.project, sender=self.send_me),
            integrations=self.integrations,
            environment=self.environment,
            release=self.release,
            traces_sample_rate=1.0,
            shutdown_timeout=20,
            send_default_pii=True,
            with_locals=False
        )


def handle_flask_exception(e):
    """
    Exception handle for usage inside Flask application
    """
    logging.error("Exception while processing {}: {}".format(flask.request.url, traceback.format_exc()))
    try:
        logging.error("Request args {}".format(flask.request.get_json(force=True)))
    except Exception:
        pass
    with sentry_sdk.configure_scope() as scope:
        scope.user = {'ip_address': flask.request.remote_addr}
        scope.set_extra('post-data', flask.request.data)
        scope.set_tag('source', 'backend')
        scope.set_tag('useragent', flask.request.user_agent.string)
        scope.set_tag('url', flask.request.url)
        sentry_sdk.capture_exception(e)
    return e


def handle_exception(e):
    """
    Exception handle for use in applications with logging integration
    """
    with sentry_sdk.configure_scope() as scope:
        scope.set_tag('source', 'backend')
        sentry_sdk.capture_exception(e)
