<commit_before>"""
    StackState.
    Zabbix telemetry integration
"""

import requests
import logging
import time

from checks import AgentCheck, CheckException
from utils.persistable_store import PersistableStore


class ZabbixHost:
    def __init__(self, hostid, host, name):
        self.host_id = hostid,
        self.host = host
        self.name = name


class ZabbixTrigger:
    def __init__(self, trigger_id, description, priority):
        self.trigger_id = trigger_id
        self.description = description
        self.priority = priority # translates to severity


class ZabbixEvent:
    def __init__(self, event_id, value, acknowledged, hosts, trigger):
        self.event_id = event_id
        self.acknowledged = acknowledged # 0/1 (not) acknowledged
        self.value = value # 0/1 -> inactive/active
        self.hosts = hosts # ZabbixHost list
        self.trigger = trigger # ZabbixTrigger

class ZabbixProblem:
    def __init__(self, event_id, host, trigger_name, acknowledged, trigger_id, severity):
        self.event_id = event_id
        self.host = host
        self.trigger_name = trigger_name
        self.acknowledged = acknowledged
        self.trigger_id = trigger_id
        self.severity = severity

class ZabbixHostStates:
    _states = {} # host_id: {trigger_id -> [ZabbixEvent]}

    def update(self, zabbix_event):
        for host in zabbix_event.hosts:
            host_id = host.host_id
            trigger_id = zabbix_event.trigger.trigger_id
            self._states[host_id][trigger_id].append(zabbix_event)

    def get_most_severe_zabbix_event(self, host_id):
        most_severe_zabbix_severity = 0
        most_severe_zabbix_event = None
        for trigger_id, zabbix_events in self._states[host_id].iteritems():
            for zabbix_event in zabbix_events:
                if zabbix_event.trigger.priority > most_severe_zabbix_severity:
                    most_severe_zabbix_event = zabbix_event
        # TODO take ACKs into account
        return most_severe_zabbix_event



class Zabbix(AgentCheck):
    SERVICE_CHECK_NAME = SOURCE_TYPE_NAME = "Zabbix"
    log = logging.getLogger('Zabbix')
    begin_epoch = None # start to listen to events from epoch timestamp
    host_states = ZabbixHostStates()

    def check(self, instance):
        """
        Integration logic
        """
        if 'url' not in instance:
            raise CheckException('Missing API url in configuration.')
        if 'user' not in instance:
            raise CheckException('Missing user in configuration.')
        if 'password' not in instance:
            raise CheckException('Missing password in configuration.')

        url = instance['url']

        topology_instance = {
            "type": self.SERVICE_CHECK_NAME,
            "url": url
        }

        self.check_connection(url)
        auth = self.login(url, instance['user'], instance['password'])

        self.start_snapshot(topology_instance)

        for zabbix_host in self.retrieve_hosts(url, auth):
            # TODO host_group as domain
            # TODO environment configurable in conf yaml
            self.process_host_topology(topology_instance, zabbix_host)

            zabbix_problems = self.retrieve_problems(url, auth, [zabbix_host.host_id]) # TODO combine host ids in one payload, batching
            self.process_problems(zabbix_host, zabbix_problems)

        self.stop_snapshot(topology_instance)

    def process_problems(self, zabbix_host, zabbix_problems):
        most_severe = None
        severe_problems = []
        for zabbix_problem in zabbix_problems:
            if not most_severe:
                most_severe = zabbix_problem.severity
                severe_problems.append(zabbix_problem)
            elif zabbix_problem.severity == most_severe:
                severe_problems.append(zabbix_problem)
            elif zabbix_problem.severity > most_severe:
                most_severe = zabbix_problem.severity
                severe_problems = [zabbix_problem]

        # TODO what if all highs/disasters are acked!

        # TODO is there an ACK in severe_problems?


        self.event({
            'timestamp': int(time.time()),
            'source_type_name': self.SOURCE_TYPE_NAME,
            'host': self.hostname,
            'tags': [
                'host_name:%s' % zabbix_host.name,
                'host_id:%s' % zabbix_host.host_id,
                'host:%s' % zabbix_host.host,
                'severity:%s' % 0  # TODO
                # TODO problems
            ]
        })


        print("")

    def process_host_health_state(self, zabbix_event):
        self.host_states.update(zabbix_event)
        for host in zabbix_event.hosts:
            zabbix_event = self.host_states.get_most_severe_zabbix_event(host.host_id)

            triggers = "triggers:[%s]" % ','.join(zabbix_event)

            self.event({
                'timestamp': int(time.time()),
                'source_type_name': self.SOURCE_TYPE_NAME,
                'host': self.hostname,
                'tags': [
                    'host:%s' % host,
                    'host_id:%s' % "",
                    triggers
                ]
            })


    def process_host_topology(self, topology_instance, zabbix_host):
        external_id = zabbix_host.host
        data = {
            'name': zabbix_host.name,
            'host_id': zabbix_host.host_id,
            'host': zabbix_host.host,
            'layer': 'Host',
            'domain': 'Zabbix', # TODO host group (+filter_
            'environment': 'Production' # TODO make configurable in yaml
        }
        component_type = "zabbix_host"

        self.component(topology_instance, external_id, component_type, data=data)

    def parse_event(self, event):
        event_id = event.get('event', None)
        value = event.get('value', None)
        acknowledged = event.get('acknowledged', None)

        hosts_items = event.get('hosts', [])
        hosts = []
        for item in hosts_items:
            host_id = item.get('hostid', None)
            host = item.get('host', None)
            host_name = item.get('name', None)
            zabbix_host = ZabbixHost(host_id, host, host_name)
            hosts.append(zabbix_host)
<commit_msg>fix the type name and hostid type<commit_after>"""
    StackState.
    Zabbix telemetry integration
"""

import requests
import logging
import time

from checks import AgentCheck, CheckException
from utils.persistable_store import PersistableStore


class ZabbixHost:
    def __init__(self, hostid, host, name):
        self.host_id = hostid
        self.host = host
        self.name = name


class ZabbixTrigger:
    def __init__(self, trigger_id, description, priority):
        self.trigger_id = trigger_id
        self.description = description
        self.priority = priority # translates to severity


class ZabbixEvent:
    def __init__(self, event_id, value, acknowledged, hosts, trigger):
        self.event_id = event_id
        self.acknowledged = acknowledged # 0/1 (not) acknowledged
        self.value = value # 0/1 -> inactive/active
        self.hosts = hosts # ZabbixHost list
        self.trigger = trigger # ZabbixTrigger

class ZabbixProblem:
    def __init__(self, event_id, host, trigger_name, acknowledged, trigger_id, severity):
        self.event_id = event_id
        self.host = host
        self.trigger_name = trigger_name
        self.acknowledged = acknowledged
        self.trigger_id = trigger_id
        self.severity = severity

class ZabbixHostStates:
    _states = {} # host_id: {trigger_id -> [ZabbixEvent]}

    def update(self, zabbix_event):
        for host in zabbix_event.hosts:
            host_id = host.host_id
            trigger_id = zabbix_event.trigger.trigger_id
            self._states[host_id][trigger_id].append(zabbix_event)

    def get_most_severe_zabbix_event(self, host_id):
        most_severe_zabbix_severity = 0
        most_severe_zabbix_event = None
        for trigger_id, zabbix_events in self._states[host_id].iteritems():
            for zabbix_event in zabbix_events:
                if zabbix_event.trigger.priority > most_severe_zabbix_severity:
                    most_severe_zabbix_event = zabbix_event
        # TODO take ACKs into account
        return most_severe_zabbix_event



class Zabbix(AgentCheck):
    SERVICE_CHECK_NAME = SOURCE_TYPE_NAME = "Zabbix"
    log = logging.getLogger('Zabbix')
    begin_epoch = None # start to listen to events from epoch timestamp
    host_states = ZabbixHostStates()

    def check(self, instance):
        """
        Integration logic
        """
        if 'url' not in instance:
            raise CheckException('Missing API url in configuration.')
        if 'user' not in instance:
            raise CheckException('Missing user in configuration.')
        if 'password' not in instance:
            raise CheckException('Missing password in configuration.')

        url = instance['url']

        topology_instance = {
            "type": self.SERVICE_CHECK_NAME,
            "url": url
        }

        self.check_connection(url)
        auth = self.login(url, instance['user'], instance['password'])

        self.start_snapshot(topology_instance)

        for zabbix_host in self.retrieve_hosts(url, auth):
            # TODO host_group as domain
            # TODO environment configurable in conf yaml
            self.process_host_topology(topology_instance, zabbix_host)

            zabbix_problems = self.retrieve_problems(url, auth, [zabbix_host.host_id]) # TODO combine host ids in one payload, batching
            self.process_problems(zabbix_host, zabbix_problems)

        self.stop_snapshot(topology_instance)

    def process_problems(self, zabbix_host, zabbix_problems):
        most_severe = None
        severe_problems = []
        for zabbix_problem in zabbix_problems:
            if not most_severe:
                most_severe = zabbix_problem.severity
                severe_problems.append(zabbix_problem)
            elif zabbix_problem.severity == most_severe:
                severe_problems.append(zabbix_problem)
            elif zabbix_problem.severity > most_severe:
                most_severe = zabbix_problem.severity
                severe_problems = [zabbix_problem]

        # TODO what if all highs/disasters are acked!

        # TODO is there an ACK in severe_problems?


        self.event({
            'timestamp': int(time.time()),
            'source_type_name': self.SOURCE_TYPE_NAME,
            'host': self.hostname,
            'tags': [
                'host_name:%s' % zabbix_host.name,
                'host_id:%s' % zabbix_host.host_id,
                'host:%s' % zabbix_host.host,
                'severity:%s' % 0  # TODO
                # TODO problems
            ]
        })


        print("")

    def process_host_health_state(self, zabbix_event):
        self.host_states.update(zabbix_event)
        for host in zabbix_event.hosts:
            zabbix_event = self.host_states.get_most_severe_zabbix_event(host.host_id)

            triggers = "triggers:[%s]" % ','.join(zabbix_event)

            self.event({
                'timestamp': int(time.time()),
                'source_type_name': self.SOURCE_TYPE_NAME,
                'host': self.hostname,
                'tags': [
                    'host:%s' % host,
                    'host_id:%s' % "",
                    triggers
                ]
            })


    def process_host_topology(self, topology_instance, zabbix_host):
        external_id = zabbix_host.host
        data = {
            'name': zabbix_host.name,
            'host_id': zabbix_host.host_id,
            'host': zabbix_host.host,
            'layer': 'Host',
            'domain': 'Zabbix', # TODO host group (+filter_
            'environment': 'Production' # TODO make configurable in yaml
        }
        component_type = {"name": "zabbix_host"}

        self.component(topology_instance, external_id, component_type, data=data)

    def parse_event(self, event):
        event_id = event.get('event', None)
        value = event.get('value', None)
        acknowledged = event.get('acknowledged', None)

        hosts_items = event.get('hosts', [])
        hosts = []
        for item in hosts_items:
            host_id = item.get('hostid', None)
            host = item.get('host', None)
            host_name = item.get('name', None)
            zabbix_host = ZabbixHost(host_id, host, host_name)
            hosts.append(zabbix_host)

{'fraction_non_alphanumeric': 0.08872576398308465, 'fraction_numerical': 0.0009574722731987553, 'mean_word_length': 2.2287480680061824, 'pattern_counts': {'":': 5, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4962194', 'n_tokens_mistral': 3864, 'n_tokens_neox': 3649, 'n_words': 803}