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

# Example output from agent:
# Put here the example output from your TCP-Based agent. If the
# <<<win_printers>>>
# PrinterStockholm                      0                   3                   0
# WH1_BC_O3_UPS                         0                   3                   0

factory_settings["win_printer_default_levels"] = {
    "warn_states": [8, 11],
    "crit_states": [9, 10],
}

WinPrinter = collections.namedtuple(  # pylint: disable=collections-namedtuple-call
    "WinPrinter", ["jobs", "status", "error"]
)


def parse_win_printers(info):
    parsed = {}
    for line in info:
        if len(line) < 4:
            continue
        try:
            parsed.setdefault(
                " ".join(line[:-3]), WinPrinter(int(line[-3]), int(line[-2]), int(line[-1]))
            )
        except ValueError:
            pass
    return parsed


@discover
def inventory_win_printers(printer_name, printer_attrs):
    # Do not discovery offline printers
    return printer_attrs.error != "9"


@get_parsed_item_data
def check_win_printers(item, params, data):
    status_map = {
        1: "Other",
        2: "Unkown",
        3: "Idle",
        4: "Printing",
        5: "Warming Up",
        6: "Stopped Printing",
        7: "Offline",
    }
    error_map = {
        0: "Unkown",
        1: "Other",
        2: "No Error",
        3: "Low Paper",
        4: "No Paper",
        5: "Low Toner",
        6: "No Toner",
        7: "Door Open",
        8: "Jammed",
        9: "Offline",
        10: "Service Requested",
        11: "Output Bin Full",
    }

    if not isinstance(params, dict):
        # Legacy params:
        if params is None:
            warn, crit = None, None
        else:
            warn, crit = params
        params = {}
        params["crit_states"] = [9, 10]
        params["warn_states"] = [8, 11]
    else:
        warn, crit = params.get("levels", (None, None))

    state = 0
    current_jobs = data.jobs
    status = data.status
    error = data.error

    error_text = ""
    if error in params["crit_states"]:
        state = 2
        error_text = "Error State: %s(!!)" % error_map[error]
    elif error in params["warn_states"]:
        state = 1
        error_text = "Error State: %s(!)" % error_map[error]

    queue_label = ""
    if crit is not None and current_jobs >= crit:
        state = 2
        queue_label = "(!!)"
    elif warn is not None and current_jobs >= warn:
        state = max(1, state)
        queue_label = "(!)"

    return state, "%s jobs current%s, State: %s, %s" % (
        current_jobs,
        queue_label,
        status_map[status],
        error_text,
    )


check_info["win_printers"] = {
    "parse_function": parse_win_printers,
    "check_function": check_win_printers,
    "group": "windows_printer_queues",
    "inventory_function": inventory_win_printers,
    "service_description": "Printer %s",
    "default_levels_variable": "win_printer_default_levels",
}
