#!/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"
    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",
}
