#!/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.
import urllib


def parse_mrpe(info):
    PluginData = collections.namedtuple("PluginData", ("name", "state", "info"))

    parsed = {}
    for line in info:
        # New Linux agent sends (check_name) in first column. Stay
        # compatible with MRPE versions not providing this info
        if line[0].startswith("("):
            name = line[0].strip('()')
            line = line[1:]
        else:
            name = None

        if len(line) < 2:
            continue
        item = urllib.unquote(line[0])
        state = line[1]
        line = line[2:]

        try:
            state = int(state)
        except ValueError:
            pass
        if state not in (0, 1, 2, 3):
            line.insert(0, "Invalid plugin status %r. Output is:" % state)
            state = 3

        # convert to original format by joining and splitting at \1 (which replaced \n)
        info = " ".join(line).split("\1")

        dataset = PluginData(name, state, info)
        parsed.setdefault(item, []).append(dataset)

    return parsed


@get_parsed_item_data
def check_mrpe(_no_item, _no_params, data):
    # This check is cluster-aware. An item might be found
    # more than once. In that case we use the best of the
    # multiple statuses (Where OK < WARN < UNKNOWN < CRIT).
    dataset = min(data, key=lambda x: (0, 1, 3, 2)[x.state])

    # First line:  OUTPUT|PERFDATA
    parts = dataset.info[0].split("|", 1)
    output = [parts[0].strip()]
    if len(parts) > 1:
        perfdata = parts[1].strip().split()
    else:
        perfdata = []

    # Further lines
    now_comes_perfdata = False
    for line in dataset.info[1:]:
        if now_comes_perfdata:
            perfdata += line.split()
        else:
            parts = line.split("|", 1)
            output.append(parts[0].strip())
            if len(parts) > 1:
                perfdata += parts[1].strip().split()
                now_comes_perfdata = True

    perf_parsed = []
    for perfvalue in perfdata:
        new_perf = parse_nagios_perfstring(perfvalue)
        if new_perf:
            perf_parsed.append(new_perf)

    # name of check command needed for PNP to choose the correct template
    if dataset.name:
        perf_parsed.append(dataset.name)
    return dataset.state, "\n".join(output), perf_parsed


check_info["mrpe"] = {
    'parse_function': parse_mrpe,
    'inventory_function': discover(),
    'check_function': check_mrpe,
    'service_description': '%s',
    'has_perfdata': True,
    'includes': ['parse_nagios.include'],
}
