#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2010             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-
# ails.  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.


# Output of old agent (< 1.1.10i2):
# AeLookupSvc        running  Application Experience Lookup Service
# Alerter            stopped  Alerter
# ALG                stopped  Application Layer Gateway Service
# AppMgmt            stopped  Application Management
# appmgr             running  Remote Server Manager

# Output of new agent (>= 1.1.10i2):
# Alerter stopped/disabled Warndienst
# ALG running/demand Gatewaydienst auf Anwendungsebene
# Apple_Mobile_Device running/auto Apple Mobile Device
# AppMgmt stopped/demand Anwendungsverwaltung
# AudioSrv running/auto Windows Audio
# BITS running/demand Intelligenter Hintergrund<FC>bertragungsdienst
# Bonjour_Service running/auto Dienst "Bonjour"

inventory_services = []

# Examples for inventory_services:
# inventory_services = [
#   "HirnTest",               # add service, if currently running
#   "TapiSrv running",        # the same
#   "TermService auto",       # add service, if start type is auto (regardless if running)
#   "BackupSrv running/auto", # add, if start type is auto and it's running
#   "~Backup.* running/auto",  # same, but add all services matching a regex
#   ( [ "termserver" ] , ALL_HOSTS, [ "HirnTest running", "Sppoller auto" ] ), # same with tags..
#   ( ALL_HOSTS, [ "!Backup.*", "FooBar auto" ] ),
# ]

def inventory_windows_services(info):

    # Handle single entries (type str)
    def add_matching_services(name, state, start_type, entry):
        if ' ' in entry and len(entry.split()) == 2:
            svc, statespec = entry.split()
        else:
            svc = entry
            statespec = "running"

        # First match name
        if svc.startswith("~"):
            if not get_regex(svc[1:]).match(name):
                return []
        elif svc != name:
            return []

        for n in statespec.split("/"):
            if n not in [ state, start_type ]:
                return []

        return [(name, None)]

    # Handle entries like ( [ "term" ], ALL_HOSTS, [ "FooBar auto", ".*TEST running" ] )
    def add_services_with_tags(name, state, start_type, entry):
        matching = []
        if len(entry) == 2:
            entry = ( [], ) + entry
        taglist, hostlist, svclist = entry
        if hosttags_match_taglist(tags_of_host(g_hostname), taglist):
            if in_extraconf_hostlist(hostlist, g_hostname):
                for svc in svclist:
                    matching += add_matching_services(name, state, start_type, svc)
        return matching


    inventory = []
    for line in info:
        name = line[0]
        if '/' in line[1]:
            state, start_type = line[1].split('/')
        else:
            state = line[1]
            start_type = "unknown"

        for entry in inventory_services:
            if type(entry) == str:
                inventory += add_matching_services(name, state, start_type, entry)
            elif type(entry) == tuple:
                inventory += add_services_with_tags(name, state, start_type, entry)
            else:
                raise MKGeneralException("Invalid entry %r in inventory_services" % entry)

    return inventory


def check_windows_services(item, params, info):
    # make sure, that thing also works for clusters:
    # here a service can be listed more than once.
    # It is sufficient of at least one "running" is
    # found.
    worststate = None
    for line in info:
        name = line[0]
        if name == item:
            # newer agents also send start type as part of state,
            # e.g. running/auto
            if '/' in line[1]:
                state, start_type = line[1].split('/')
            else:
                state = line[1]
                start_type = "unknown"

            displayname = " ".join(line[2:])
            if state == 'running':
                return (0, "OK - running (start type is %s): %s" % (start_type, displayname))
            worststate = state
            worst_start_type = start_type
    if worststate:
        return (2, "CRIT - %s (start type is %s): %s" % (worststate, worst_start_type, displayname))
    else:
        return (3, "UNKNOWN - service not found")


check_info['services'] = (check_windows_services, "service_%s", 0, inventory_windows_services)
