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

# <<<postgres_stats>>>
# [databases_start]
# postgres
# testdb
# datenbank
# [databases_end]
# datname;sname;tname;vtime;atime
# postgres;pg_catalog;pg_statistic;-1;-1
# postgres;pg_catalog;pg_type;-1;-1
# postgres;pg_catalog;pg_authid;-1;-1
# postgres;pg_catalog;pg_attribute;-1;-1


def inventory_postgres_stats(parsed):
    for db in parsed.keys():
        yield "VACUUM %s"  % db, {}
        yield "ANALYZE %s" % db, {}

def check_postgres_stats(item, params, parsed):
    is_vacuum = item.startswith("VACUUM")
    database  = item.split(" ", 1)[1]

    if database in parsed:
        stats_field = is_vacuum and "vtime" or "atime"
        # namespace,  tablename, last_vacuum,  last_analyze
        # ['public', 'my_table', '1424352356', '1424352356'],
        oldest_element = None
        never_checked  = []
        for line in parsed[database]:
            # Tables with metadata are ignored
            if line["sname"] == "pg_catalog":
                continue

            value = line[stats_field]

            if value == "-1" or value == "":
                never_checked.append(line["tname"])
                continue

            last_time = int(value)

            if not oldest_element or last_time < oldest_element[stats_field]:
                oldest_element = line

        if oldest_element:
            oldest_time = int(oldest_element[stats_field])
            warn, crit  = params.get("last_%s" % (is_vacuum and "vacuum" or "analyze"),
                                    (None, None))

            yield 0, "Table: %s" % oldest_element["tname"]

            now = time.time()
            state = 0
            if crit and now - crit > oldest_time:
                state = 2
            elif warn and now - warn > oldest_time:
                state = 1

            extra_info = ""
            if state:
                extra_info = " (Levels at %s/%s)" % (get_age_human_readable(warn), get_age_human_readable(crit))
            yield state, "Time since last vacuum %s%s" % (get_age_human_readable(now - oldest_time), extra_info)
        elif not never_checked:
            yield 0, "Contains no tables"

        if never_checked:
            yield 1, "%d tables were never %s: %s%s" % \
                (len(never_checked), is_vacuum and "vacuumed" or "analyzed",
                "/".join(never_checked[:5]),
                (len(never_checked) > 5 and " (first %d shown)" % min(5, len(never_checked)) or ""))


check_info['postgres_stats'] = {
    "parse_function"          : parse_postgres_dbs,
    "check_function"          : check_postgres_stats,
    "inventory_function"      : inventory_postgres_stats,
    "service_description"     : "PostgreSQL %s",
    "group"                   : "postgres_maintenance"
}

