#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

factory_settings['informix_transactions_default_levels'] = {
    'levels': (70, 80),
}
#first line represents current log ID
#line[2]= sessionID
#line[3]= number of locks kept by sessionID
#line[4]= begin log position
#line[5]= current log position


def parse_informix_transactions(info):
    parsed = {}
    instance = None
    entry = None
    for line in info:
        if line[0].startswith("[[[") and line[0].endswith("]]]"):
            instance = line[0][3:-3]
        elif instance is not None:
            entry = {}
            parsed.setdefault(instance, [])
            parsed[instance].append(entry)

            if len(line) > 2: 
                if "C" in line[2]:
                    entry.setdefault("current_log_id", line[3])
                elif entry is not None:
                    if ":" in str(line[4]):
                        line[4] = line[4].split(":",1)[0]
                    if ":" in str(line[5]):
                        line[5] = line[5].split(":",1)[0]
               
                    entry.setdefault("session", [line[2], line[3], line[4], line[5]])
    return parsed

#############Transaction with more than 70 locks
def inventory_informix_transactions_locks(parsed):
    return [(instance, {}) for instance in parsed]


def check_informix_transactions_locks(item, params, parsed):
    if item in parsed:
        warn, crit = params['levels']
        data = parsed[item]
        infotext = ""
        state = 0
        for session in data[1:]:
            if session and session["session"][2]:
                if "-" not in session["session"][1]:
                    if int(session["session"][1]) >= crit:
                        state = 2
                        infotext += 'Session with ID %s has %s locks; ' % (session["session"][0], session["session"][1])
                    elif int(session["session"][1]) >= warn:
                        state = 1
                        infotext += 'Session with ID %s has %s locks; ' % (session["session"][0], session["session"][1])

        if state:
            infotext += " (warn/crit at %s/%s)" % (warn, crit)
        else:
            infotext = 'There are no sessions with high number of locks' 
        return state, infotext, []


check_info['informix_transactions.locks'] = {
    'parse_function': parse_informix_transactions,
    'inventory_function': inventory_informix_transactions_locks,
    'check_function': check_informix_transactions_locks,
    'has_perfdata': False,
    'service_description': 'Informix sessions nLocks %s',
    "group": "informix_nlocks",
    'default_levels_variable': 'informix_transactions_default_levels',
}


#############Sesiuni fara activitate in logul curent
def inventory_informix_transactions_activity(parsed):
    return [(instance, {}) for instance in parsed]


def check_informix_transactions_activity(item, no_params, parsed):
    if item in parsed:
        data = parsed[item]
        state = 0
        infotext = ''
        for session in data[1:]:
            if session and session["session"][2]:
                if "-" not in session["session"][2]:
                    if int(session["session"][2]) < int(data[0]['current_log_id']):
                        state = 2
                        infotext += "Session %s doesn't have activity in current log; " % (session["session"][0])


        if not state:
            infotext = 'There are no sessions with no activity in current log; ' 

        return state, infotext, []


check_info['informix_transactions.activity'] = {
    'parse_function': parse_informix_transactions,
    'inventory_function': inventory_informix_transactions_activity,
    'check_function': check_informix_transactions_activity,
    'has_perfdata': False,
    'service_description': 'Informix sessions activity %s',
}

#############Long transactions (over 3 logical logs used)
def inventory_informix_long_transactions(parsed):
    return [(instance, {}) for instance in parsed]


def check_informix_long_transactions(item, no_params, parsed):
    if item in parsed:
        data = parsed[item]
        state = 0
        infotext = '' 
        for session in data[1:]:
            if session and session["session"][2]:
                if "-" not in session["session"][2]:
                    if (int(session["session"][2]) - int(session["session"][3])) < 2:
                        state = 2
                        infotext += "Session %s is using more than 3 logical logs; " % (session["session"][0])


        if not state:
            infotext = 'There are no long running transactions; ' 

        return state, infotext, []


check_info['informix_transactions.long_transactions'] = {
    'parse_function': parse_informix_transactions,
    'inventory_function': inventory_informix_long_transactions,
    'check_function': check_informix_long_transactions,
    'has_perfdata': False,
    'service_description': 'Informix sessions Long transactions %s',
}