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


# .1.3.6.1.4.1.110901.1.2.1.1.1.2.1       lib status
# .1.3.6.1.4.1.110901.1.2.2.1.1.8.1.1.x   drive x status
# .1.3.6.1.4.1.110901.1.3.1.1.4.1         actor status

# .1.3.6.1.4.1.110901.1.4.1.0             archive status
# .1.3.6.1.4.1.110901.1.4.2.0             archive objects count
# .1.3.6.1.4.1.110901.1.4.3.0             blank tapes count
# .1.3.6.1.4.1.110901.1.4.4.0             remaining size on tapes
# .1.3.6.1.4.1.110901.1.4.5.0             total size on tapes


#
# Note: These checks was designed a bit atypically (for no good reason):
#   The drive, actor, archive, tapes and library checks are subchecks of the status
#   check although none of these checks share the same oids.
#   As a result, "info" is always a list of 6 sublists and each check only
#   acceses exactly one of the sublists.
#



#.
#   .--Status--------------------------------------------------------------.
#   |                    ____  _        _                                  |
#   |                   / ___|| |_ __ _| |_ _   _ ___                      |
#   |                   \___ \| __/ _` | __| | | / __|                     |
#   |                    ___) | || (_| | |_| |_| \__ \                     |
#   |                   |____/ \__\__,_|\__|\__,_|___/                     |
#   |                                                                      |
#   '----------------------------------------------------------------------'



def item_name_oracle_diva_csm(name, element_id):
    return ("%s %s" % (name, element_id)).strip()


def inventory_oracle_diva_csm_status(name, idx, info):
    for line in info[idx]:
        if len(line) == 2:
            element_id, reading = line
        else:
            element_id = ''

        yield item_name_oracle_diva_csm(name, element_id), None


def status_result_oracle_diva_csm(reading):
    if reading == '1':
        return 0, "online"
    elif reading == '2':
        return 2, "offline"
    elif reading == '3':
        return 1, "unknown"
    else:
        return 3, "unexpected state"


def check_oracle_diva_csm_status(name, idx, item, params, info):
    for line in info[idx]:
        if len(line) == 2:
            element_id, reading = line
        else:
            element_id = ''
            reading = line[0]

        if item_name_oracle_diva_csm(name, element_id) == item:
            return status_result_oracle_diva_csm(reading)


check_info['oracle_diva_csm'] = {
    "check_function"      : lambda item, params, info: check_oracle_diva_csm_status("Library", 0, item, params, info),
    "inventory_function"  : lambda info: inventory_oracle_diva_csm_status("Library", 0, info),
    "service_description" : "DIVA Status %s",
    "snmp_info"           : [ ( ".1.3.6.1.4.1.110901.1.2.1.1.1", [ '1',   '2' ] ),   # lib status
                              ( ".1.3.6.1.4.1.110901.1.2.2.1.1", [ '3',   '8' ] ),   # drive status
                              ( ".1.3.6.1.4.1.110901.1.3.1.1",   [ '2',   '4' ] ),   # actor status
                              ( ".1.3.6.1.4.1.110901.1.4",       [ '1' ] ),          # archive status
                              ( ".1.3.6.1.4.1.110901.1.4",       [ '2',      # object count
                                                                   '4',      # remaining size
                                                                   '5' ] ),  # total size
                              ( ".1.3.6.1.4.1.110901.1.4",       [ '3' ] ),  # blank tape count
                            ],
    "snmp_scan_function"  : lambda oid: oid(".1.3.6.1.2.1.1.2.0") == ".1.3.6.1.4.1.311.1.1.3.1.2",
}

check_info['oracle_diva_csm.drive'] = {
    "check_function"      : lambda item, params, info: check_oracle_diva_csm_status("Drive", 1, item, params, info),
    "inventory_function"  : lambda info: inventory_oracle_diva_csm_status("Drive", 1, info),
    "service_description" : "DIVA Status %s",
}

check_info['oracle_diva_csm.actor'] = {
    "check_function"      : lambda item, params, info: check_oracle_diva_csm_status("Actor", 2, item, params, info),
    "inventory_function"  : lambda info: inventory_oracle_diva_csm_status("Actor", 2, info),
    "service_description" : "DIVA Status %s",
}


check_info['oracle_diva_csm.archive'] = {
    "check_function"      : lambda item, params, info: check_oracle_diva_csm_status("Manager", 3, item, params, info),
    "inventory_function"  : lambda info: inventory_oracle_diva_csm_status("Manager", 3, info),
    "service_description" : "DIVA Status %s",
}



#.
#   .--Managed Objects-----------------------------------------------------.
#   |              __  __                                  _               |
#   |             |  \/  | __ _ _ __   __ _  __ _  ___  __| |              |
#   |             | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \/ _` |              |
#   |             | |  | | (_| | | | | (_| | (_| |  __/ (_| |              |
#   |             |_|  |_|\__,_|_| |_|\__,_|\__, |\___|\__,_|              |
#   |                                       |___/                          |
#   |                    ___  _     _           _                          |
#   |                   / _ \| |__ (_) ___  ___| |_ ___                    |
#   |                  | | | | '_ \| |/ _ \/ __| __/ __|                   |
#   |                  | |_| | |_) | |  __/ (__| |_\__ \                   |
#   |                   \___/|_.__// |\___|\___|\__|___/                   |
#   |                            |__/                                      |
#   '----------------------------------------------------------------------'


def inventory_oracle_diva_csm_objects(info):
    if len(info) > 4 and len(info[4]) > 0:
        yield None, None


def check_oracle_diva_csm_objects(item, params, info):
    GB = 1024 * 1024 * 1024
    if len(info) > 4 and len(info[4]) > 0:
        object_count, remaining_size, total_size = map(int, info[4][0])

        infotext = "managed objects: %s, remaining size: %s GB of %s GB" % (object_count, remaining_size, total_size)

        return 0, infotext, [("managed_object_count", object_count),
                            ("storage_used", (total_size - remaining_size) * GB,
                            None, None, 0, total_size * GB)]


check_info['oracle_diva_csm.objects'] = {
    "check_function"      : check_oracle_diva_csm_objects,
    "inventory_function"  : inventory_oracle_diva_csm_objects,
    "has_perfdata"        : True,
    "service_description" : "DIVA Managed Objects",
}


#.
#   .--Tapes---------------------------------------------------------------.
#   |                      _____                                           |
#   |                     |_   _|_ _ _ __   ___  ___                       |
#   |                       | |/ _` | '_ \ / _ \/ __|                      |
#   |                       | | (_| | |_) |  __/\__ \                      |
#   |                       |_|\__,_| .__/ \___||___/                      |
#   |                               |_|                                    |
#   '----------------------------------------------------------------------'


oracle_diva_csm_tapes_default_levels = (5, 1)       # number of remaining blank tapes. invented levels


def inventory_oracle_diva_csm_tapes(info):
    if len(info) > 5 and len(info[5]) > 0 and len(info[5][0]) > 0:
        yield None, 'oracle_diva_csm_tapes_default_levels'


def check_oracle_diva_csm_tapes(item, params, info):
    if len(info) > 5 and len(info[5]) > 0 and len(info[5][0]) > 0:
        blank_tapes = int(info[5][0][0])
        warn, crit = params
        state = blank_tapes <= crit and 2 \
            or blank_tapes <= warn and 1 \
            or 0

        infotext = "blank tapes %d" % blank_tapes
        if state > 0:
            infotext += " (warn/crit at %d/%d)" % (warn, crit)

        return state, infotext, [("tapes_free", blank_tapes)]


check_info['oracle_diva_csm.tapes'] = {
    "check_function"          : check_oracle_diva_csm_tapes,
    "inventory_function"      : inventory_oracle_diva_csm_tapes,
    "group"                   : "blank_tapes",
    "has_perfdata"            : True,
    "service_description"     : "DIVA Blank Tapes",
}


