#!/usr/bin/env python
"""
SNMP agent to parse CPU and ACPI TZ sensors from sysctl info on FreeBSD,
updating every 30 seconds

This implementation uses linux 'lm-sensors' OID tree
"""

from subprocess import Popen, PIPE
from seine.snmp.agent import SNMPAgent, Item

OID_PREFIX = '1.3.6.1.4.1.2021.13.16'


class FreeBSDTemperaturesMonitorAgent(SNMPAgent):
    def __init__(self):
        super(FreeBSDTemperaturesMonitorAgent, self).__init__(OID_PREFIX, reload_interval=30)

        self.index_tree = self.register_tree('{0}.2.1.1'.format(OID_PREFIX))
        self.names_tree = self.register_tree('{0}.2.1.2'.format(OID_PREFIX))
        self.value_tree = self.register_tree('{0}.2.1.3'.format(OID_PREFIX))

        self.reload()

    def load_cpu_temperatures(self):
        p = Popen(['sysctl', '-a', 'dev.cpu'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()

        if p.returncode != 0:
            self.log.debug('ERROR reading CPU temperatures: {0}'.format(stderr))
            return

        for line in stdout.split('\n'):
            if line.strip() == '':
                continue

            try:
                key, value = line.split(':', 1)
                key = key.rstrip(':')
                if key.split('.')[-1] != 'temperature':
                    continue

                index = int(key.split('.')[2])
                value = int(float(value.rstrip('C')) * 1000)

                self.index_tree.add_values('integer', [self.sensor_index])
                self.names_tree.add_values('string', ['CPU Core {0:d}'.format(index)])
                self.value_tree.add_values('gauge', [value])
                self.sensor_index += 1

            except ValueError:
                continue

    def load_acpi_thermal_temperatures(self):
        p = Popen(['sysctl', '-a', 'hw.acpi.thermal'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()

        if p.returncode != 0:
            self.log.debug('ERROR reading ACPI thermal temperatures: {0}'.format(stderr))
            return

        for line in stdout.split('\n'):
            if line.strip() == '':
                continue

            try:
                key, value = line.split(':', 1)
                key = key.rstrip(':')
                if key.split('.')[-1] != 'temperature':
                    continue

                index = int(key.split('.')[3][2:])
                value = int(float(value.rstrip('C')) * 1000)

                self.index_tree.add_values('integer', [self.sensor_index])
                self.names_tree.add_values('string', ['ACPI TZ {0:d}'.format(index)])
                self.value_tree.add_values('gauge', [value])
                self.sensor_index += 1
            except ValueError, emsg:
                continue

    def reload(self):
        self.clear()
        self.sensor_index = 1
        self.load_cpu_temperatures()
        self.load_acpi_thermal_temperatures()

FreeBSDTemperaturesMonitorAgent().run()

