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

# <<<omd_apache:sep(124)>>>
# [heute]
# /heute/check_mk/view.py?view_name=allhosts&_display_options=htbfcoderuw&_do_actions=&_ajaxid=1433252694|200|5067|13465
# /heute/check_mk/sidebar_snapin.py?names=tactical_overview,admin|200|4046|8109
# /heute/check_mk/index.py?start_url=%2Fheute%2Fcheck_mk%2Fview.py%3Fview_name%3Dallhosts|200|515|7528
# /heute/check_mk/view.py?view_name=allhosts|200|37656|57298
# /heute/check_mk/side.py|200|39885|108178
# /heute/check_mk/js/graphs-2015.06.02.js|200|28895|1823
# [heute2]

omd_apache_patterns = [
    # perf keys         url matching regex
    ('cmk_views', r'^check_mk/view\.py'),
    ('cmk_wato', r'^check_mk/wato\.py'),
    ('cmk_bi', r'^check_mk/bi\.py'),
    ('cmk_snapins', r'^check_mk/sidebar_snapin\.py'),
    ('cmk_dashboards', r'^check_mk/dashboard\.py'),
    ('cmk_other', r'^check_mk/.*\.py'),
    ('nagvis_snapin', r'^nagvis/server/core/ajax_handler\.php?mod=Multisite&act=getMaps'),
    ('nagvis_ajax', r'^nagvis/server/core/ajax_handler\.php'),
    ('nagvis_other', r'^nagvis/.*\.php'),
    ('images', r'\.(jpg|png|gif)$'),
    ('styles', r'\.css$'),
    ('scripts', r'\.js$'),
    ('other', '.*'),
]


# Parses the agent data to a dictionary, using the site name as keys
#  which holds
def parse_omd_apache(info):
    parsed = {}
    site = None
    for line in info:
        if line[0][0] == '[':
            site = line[0][1:-1]
            parsed[site] = []
        elif site:
            parsed[site].append(line)
    return parsed


def inventory_omd_apache(parsed):
    return [(k, None) for k in parsed.keys()]


def check_omd_apache(item, _no_params, parsed):
    # First initialize all possible values to be able to always report all perf keys
    stats = {'requests': {}, 'secs': {}, 'bytes': {}}
    for key, pattern in omd_apache_patterns:
        stats['requests'][key] = 0
        stats['secs'][key] = 0
        stats['bytes'][key] = 0

    if item not in parsed:
        return
    elif not parsed[item]:
        yield 0, "No activity since last check"
        return

    for line in parsed[item]:
        if len(line) < 3:
            continue
        elif len(line) == 4:
            url, _status, size_bytes, microsec = line
        else:
            url = " ".join(line[:-3])
            _status, size_bytes, microsec = line[-3:]

        for key, pattern in omd_apache_patterns:
            # make url relative to site directory
            if regex(pattern).search(url[len('/' + item + '/'):]):
                stats['requests'].setdefault(key, 0)
                stats['requests'][key] += 1

                stats['secs'].setdefault(key, 0)
                stats['secs'][key] += int(microsec) / 1000.0 / 1000.0

                stats['bytes'].setdefault(key, 0)
                stats['bytes'][key] += int(size_bytes)

                break  # don't call a line twice

    # Now process the result. Break down the gathered values to values per second.
    # the output is showing total values, for the graphing we provide detailed data
    this_time = time.time()
    for ty, title in [
        ('requests', 'Requests/s'),
        ('secs', 'Seconds serving/s'),
        ('bytes', 'Sent/s'),
    ]:
        total = 0
        for key, value in sorted(stats[ty].items(), key=lambda k_v: k_v[1], reverse=True):
            rate = get_rate("omd_apache.%s.%s.%s" % (item, ty, key),
                            this_time,
                            value,
                            onwrap=SKIP,
                            is_rate=True)
            total += rate
            yield 0, '', [(ty + '_' + key, rate)]

        total = get_bytes_human_readable(total) if ty == "bytes" else ("%.2f" % total)
        yield 0, '%s %s' % (total, title)


check_info['omd_apache'] = {
    'parse_function': parse_omd_apache,
    'check_function': check_omd_apache,
    'inventory_function': inventory_omd_apache,
    'service_description': 'OMD %s apache',
    'has_perfdata': True,
}
