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


#   .--general-------------------------------------------------------------.
#   |                                                  _                   |
#   |                   __ _  ___ _ __   ___ _ __ __ _| |                  |
#   |                  / _` |/ _ \ '_ \ / _ \ '__/ _` | |                  |
#   |                 | (_| |  __/ | | |  __/ | | (_| | |                  |
#   |                  \__, |\___|_| |_|\___|_|  \__,_|_|                  |
#   |                  |___/                                               |
#   +----------------------------------------------------------------------+

mbg_lantime_ng_refclock_types = {
    "0": "unknown",
    "1": "gps166",
    "2": "gps167",
    "3": "gps167SV",
    "4": "gps167PC",
    "5": "gps167PCI",
    "6": "gps163",
    "7": "gps168PCI",
    "8": "gps161",
    "9": "gps169PCI",
    "10": "tcr167PCI",
    "11": "gps164",
    "12": "gps170PCI",
    "13": "pzf511",
    "14": "gps170",
    "15": "tcr511",
    "16": "am511",
    "17": "msf511",
    "18": "grc170",
    "19": "gps170PEX",
    "20": "gps162",
    "21": "ptp270PEX",
    "22": "frc511PEX",
    "23": "gen170",
    "24": "tcr170PEX",
    "25": "wwvb511",
    "26": "mgr170",
    "27": "jjy511",
    "28": "pzf600",
    "29": "tcr600",
    "30": "gps180",
    "31": "gln170",
    "32": "gps180PEX",
    "33": "tcr180PEX",
    "34": "pzf180PEX",
    "35": "mgr180",
    "36": "msf600",
    "37": "wwvb600",
    "38": "jjy600",
    "39": "gps180HS",
    "40": "gps180AMC",
    "41": "esi180",
    "42": "cpe180",
    "43": "lno180",
    "44": "grc180",
    "45": "liu",
    "46": "dcf600HS",
    "47": "dcf600RS",
    "48": "mri",
    "49": "bpe",
    "50": "gln180Pex",
    "51": "n2x",
    "52": "rsc180",
    "53": "lneGb",
    "54": "lnePpg180",
    "55": "scg",
    "56": "mdu300",
    "57": "sdi",
    "58": "fdm180",
    "59": "spt",
    "60": "pzf180",
    "61": "rel1000",
}


def mbg_lantime_ng_generalstate(clock_type, usage, state, substate):
    refclock_usages = {
        "0": "not available",
        "1": "secondary",
        "2": "compare",
        "3": "primary",
    }

    refclock_states = {
        "0": (2, "not available"),
        "1": (0, "synchronized"),
        "2": (1, "not synchronized"),
    }

    # Translation for values of MBG-SNMP-LTNG-MIB::mbgLtNgRefclockSubstate
    refclock_substates = {
        "0": "not available",
        "1": "GPS sync",
        "2": "GPS tracking",
        "3": "GPS antenna disconnected",
        "4": "GPS warm boot",
        "5": "GPS cold boot",
        "6": "GPS antenna short circuit",
        "50": "LW never sync",
        "51": "LW not sync",
        "52": "LW sync",
        "100": "TCR not sync",
        "101": "TCT sync",
        "149": "MRS internal oscillator sync",
        "150": "MRS GPS sync",
        "151": "MRS 10Mhz sync",
        "152": "MRS PPS in sync",
        "153": "MRS 10Mhz PPS in sync",
        "154": "MRS IRIG sync",
        "155": "MRS NTP sync",
        "156": "MRS PTP IEEE 1588 sync",
        "157": "MRS PTP over E1 sync",
        "158": "MRS fixed frequency in sync",
        "159": "MRS PPS string sync",
        "160": "MRS variable frequency GPIO sync",
        "161": "MRS reserved",
        "162": "MRS DCF77 PZF sync",
        "163": "MRS longwave sync",
        "164": "MRS GLONASS GPS sync",
        "165": "MRS HAVE QUICK sync",
        "166": "MRS external oscillator sync",
        "167": "MRS SyncE",
    }

    state, state_txt = refclock_states[state]
    detailed_state_txt = (' (%s)' % refclock_substates[substate]
                          if substate != '0' else '')
    infotext = "Type: %s, Usage: %s, State: %s%s" % (
        mbg_lantime_ng_refclock_types[clock_type], refclock_usages[usage],
        state_txt, detailed_state_txt
    )

    return state, infotext


#.
#   .--gps refclocks-------------------------------------------------------.
#   |                                  __      _            _              |
#   |       __ _ _ __  ___   _ __ ___ / _| ___| | ___   ___| | _____       |
#   |      / _` | '_ \/ __| | '__/ _ \ |_ / __| |/ _ \ / __| |/ / __|      |
#   |     | (_| | |_) \__ \ | | |  __/  _| (__| | (_) | (__|   <\__ \      |
#   |      \__, | .__/|___/ |_|  \___|_|  \___|_|\___/ \___|_|\_\___/      |
#   |      |___/|_|                                                        |
#   +----------------------------------------------------------------------+

# number of good satellites
mbg_lantime_refclock_default_levels = (3, 3)


def inventory_lantime_ng_refclock_gps(info):
    for line in info:
        if mbg_lantime_ng_refclock_types[line[1]].startswith("gps"):
            yield (line[0], 'mbg_lantime_refclock_default_levels')


def check_lantime_ng_refclock_gps(item, params, info):
    for (index, clock_type, usage, state, substate, status_a, max_status_a,
            _, _, _, leapsecond_date) in info:

        if item == index:
            yield mbg_lantime_ng_generalstate(clock_type, usage, state, substate)

            if substate not in ("1", "2"):
                yield 0, "Next leap second: %s" % str(leapsecond_date)

            good_sats = int(status_a)
            total_sats = int(max_status_a)
            # levels are not "at" but "below" because we must be
            # compatible with old mbg_lantime_refclock check
            warn, crit = params
            if good_sats < crit:
                state = 2
                levels_txt = " (warn/crit below %d/%d)" % params
            elif good_sats < warn:
                state = 1
                levels_txt = " (warn/crit below %d/%d)" % params
            else:
                state = 0
                levels_txt = ""

            yield state, "Satellites: %d/%d%s" % (good_sats, total_sats, levels_txt)


check_info["mbg_lantime_ng_refclock.gps"] = {
    "check_function"            : check_lantime_ng_refclock_gps,
    "inventory_function"        : inventory_lantime_ng_refclock_gps,
    "service_description"       : "LANTIME Refclock %s",
    "has_perfdata"              : True,
}

#.
#   .--other refclocks-----------------------------------------------------.
#   |                            _   _                                     |
#   |                       ___ | |_| |__   ___ _ __                       |
#   |                      / _ \| __| '_ \ / _ \ '__|                      |
#   |                     | (_) | |_| | | |  __/ |                         |
#   |                      \___/ \__|_| |_|\___|_|                         |
#   |                                                                      |
#   |                         __      _            _                       |
#   |               _ __ ___ / _| ___| | ___   ___| | _____                |
#   |              | '__/ _ \ |_ / __| |/ _ \ / __| |/ / __|               |
#   |              | | |  __/  _| (__| | (_) | (__|   <\__ \               |
#   |              |_|  \___|_|  \___|_|\___/ \___|_|\_\___/               |
#   |                                                                      |
#   +----------------------------------------------------------------------+


def inventory_lantime_ng_refclock(info):
    for line in info:
        if not mbg_lantime_ng_refclock_types[line[1]].startswith("gps"):
            yield (line[0], None)


def check_lantime_ng_refclock(item, _no_params, info):

    for (index, clock_type, usage, state, substate, status_a, max_status_a,
            status_b, max_status_b, _, _) in info:

        if item == index:
            yield mbg_lantime_ng_generalstate(clock_type, usage, state, substate)

            field_strength = round(float(status_b) / float(max_status_b) * 100.0)
            perfdata = [("field_strength", field_strength)]

            yield 0, "Field strength: %d%%" % field_strength, perfdata

            # only used for longwave - pzf refclocks
            if max_status_a != "0":
                correlation = round(float(status_a) / float(max_status_a) * 100.0)
                perfdata = [("correlation", correlation)]
                yield 0, "Correlation: %d%%" % correlation, perfdata


check_info["mbg_lantime_ng_refclock"] = {
    "check_function"            : check_lantime_ng_refclock,
    "inventory_function"        : inventory_lantime_ng_refclock,
    "service_description"       : "LANTIME Refclock %s",
    "has_perfdata"              : True,
    "snmp_info"                 : (".1.3.6.1.4.1.5597.30.0.1.2.1", [
        1,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockIndex
        2,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockType
        3,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockUsage
        4,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockState
        5,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockSubstate
        6,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockStatusA
        7,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockMaxStatusA
        8,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockStatusB
        9,   # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockMaxStatusB
        10,  # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockAdditionalInfo
        11,  # MBG-SNMP-LTNG-MIB::mbgLtNgRefclockLeapSecondDate
    ]),
    "snmp_scan_function"        : snmp_scan_mbg_lantime_ng_hw,
    "includes"                  : ["mbg_lantime.include"],
}
