#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

# This agent uses UPNP API calls to the Fritz!Box to gather information
# about connection configuration and status.

import getopt, sys, socket, urllib2, traceback, re, pprint

def usage():
    sys.stderr.write("""Check_MK ALLNET IP-Sensoric Agent

USAGE: agent_allnet_ip_sensoric [OPTIONS] HOST
       agent_allnet_ip_sensoric -h

ARGUMENTS:
  HOST                          Host name or IP address of your ALLNET IP-Sensoric

OPTIONS:
  -h, --help                    Show this help message and exit
  -t, --timeout SEC             Set the network timeout to <SEC> seconds.
                                Default is 10 seconds. Note: the timeout is not
                                applied to the whole check, instead it is used for
                                the http query only.
  --debug                       Debug mode: let Python exceptions come through
""")

short_options = 'h:t:d'
long_options  = [
    'help', 'timeout=', 'debug'
]

host_address      = None
opt_debug         = False
opt_timeout       = 10

try:
    opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
except getopt.GetoptError, err:
    sys.stderr.write("%s\n" % err)
    sys.exit(1)

for o,a in opts:
    if o in [ '--debug' ]:
        opt_debug = True
    elif o in [ '-t', '--timeout' ]:
        opt_timeout = int(a)
    elif o in [ '-h', '--help' ]:
        usage()
        sys.exit(0)

if len(args) == 1:
    host_address = args[0]
elif not args:
    sys.stderr.write("ERROR: No host given.\n")
    sys.exit(1)
else:
    sys.stderr.write("ERROR: Please specify exactly one host.\n")
    sys.exit(1)

socket.setdefaulttimeout(opt_timeout)

class RequestError(Exception):
    pass

def get_allnet_ip_sensoric_info():
    global g_device, g_version
    url = 'http://%s/xml/sensordata.xml' % (host_address)

    headers = {
        'User-agent':   'Check_MK agent_allnet_ip_sensoric',
    }

    if opt_debug:
        sys.stdout.write('============================\n')
        sys.stdout.write('URL: %s\n' % url)

    try:
        req = urllib2.Request(url, None, headers)
        handle = urllib2.urlopen(req)
    except Exception, e:
        if opt_debug:
            sys.stdout.write('----------------------------\n')
            sys.stdout.write(traceback.format_exc())
            sys.stdout.write('============================\n')
        raise RequestError('Error during http call')

    infos    = handle.info()
    contents = handle.read()

    if opt_debug:
        sys.stdout.write('----------------------------\n')
        sys.stdout.write('Server: %s\n' % infos['SERVER'])
        sys.stdout.write('----------------------------\n')
        sys.stdout.write(contents + '\n')
        sys.stdout.write('============================\n')

    attrs = {}

    context = None
    for line in contents.splitlines():

        match = re.search('<(sensor[0-9]+|system)>', line)
        if match:
            context = match.group(1)
            continue

        match = re.search('</(sensor[0-9]+|system)>', line)
        if match:
            context = None
            continue

        match = re.search('<(\w+)>(.+)</\w+>', line)
        if match and context:
            attrs["%s.%s" % (context, match.group(1))] = match.group(2)

    if opt_debug:
        sys.stdout.write('Parsed: %s\n' % pprint.pformat(attrs))

    return attrs

try:
    status = {}
    try:
        status.update(get_allnet_ip_sensoric_info())
    except:
        if opt_debug:
            raise

    sys.stdout.write('<<<check_mk>>>\n')
    if "system.devicetype" in status.keys():
        sys.stdout.write('AgentOS: %s\n' % status["system.devicetype"])
    else:
        sys.stdout.write('AgentOS: unknown\n')

    sys.stdout.write('<<<allnet_ip_sensoric:sep(59)>>>\n')
    for key, value in sorted(status.items()):
        sys.stdout.write('%s;%s\n' % (key, value))

except:
    if opt_debug:
        raise
    sys.stderr.write('Unhandled error: %s' % traceback.format_exc())
