#!/usr/bin/python
# VictorOPS

# -*- coding: utf-8 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2018             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.
r"""
Send notification messages to VictorOPS
=======================================

Create a JSON message to be sent to VictorOPS REST API
"""
from __future__ import unicode_literals
import sys
import requests
import re
import os

from typing import AnyStr, Dict, Optional, Tuple  # pylint: disable=unused-import

import cmk.password_store


def cmk_links(context):
    # type: (Dict) -> Tuple[Optional[str], Optional[str]]
    if context.get("PARAMETER_URL_PREFIX"):
        url_prefix = context["PARAMETER_URL_PREFIX"]
    elif context.get("PARAMETER_URL_PREFIX_MANUAL"):
        url_prefix = context["PARAMETER_URL_PREFIX_MANUAL"]
    elif context.get("PARAMETER_URL_PREFIX_AUTOMATIC") == "http":
        url_prefix = "http://%s/%s" % (context["MONITORING_HOST"], context["OMD_SITE"])
    elif context.get("PARAMETER_URL_PREFIX_AUTOMATIC") == "https":
        url_prefix = "https://%s/%s" % (context["MONITORING_HOST"], context["OMD_SITE"])
    else:
        url_prefix = None

    if url_prefix:
        base_url = re.sub('/check_mk/?', '', url_prefix)
        host_url = base_url + context['HOSTURL']

        if context['WHAT'] == 'SERVICE':
            service_url = base_url + context['SERVICEURL']
            return host_url, service_url

        return host_url, None

    return None, None


def extend_context_with_link_urls(context, link_template):
    # type: (Dict, AnyStr) -> None

    host_url, service_url = cmk_links(context)

    if host_url:
        context['LINKEDHOSTNAME'] = link_template.format(host_url, context['HOSTNAME'])
    else:
        context['LINKEDHOSTNAME'] = context['HOSTNAME']

    if service_url:
        context['LINKEDSERVICEDESC'] = link_template.format(service_url, context['SERVICEDESC'])
    else:
        context['LINKEDSERVICEDESC'] = context.get('SERVICEDESC', '')


def translate_states(state):
    if state in ['OK', 'UP']:
        return 'OK'
    if state in ['CRITICAL', 'DOWN']:
        return 'CRITICAL'
    if state in ['UNKNOWN', 'UNREACHABLE']:
        return 'INFO'
    return state  # This is WARNING


def victorops_msg(context):
    # type: (Dict) -> Dict
    """Build the message for slack"""

    extend_context_with_link_urls(context, '{0}')

    if context.get('WHAT', None) == "SERVICE":
        state = translate_states(context["SERVICESTATE"])
        entity_id = '{SERVICEDESC}/{HOSTNAME}:{HOSTADDRESS}'.format(**context).replace(" ", "")
        title = "{SERVICEDESC} on {HOSTNAME}".format(**context)
        text = "{SERVICEOUTPUT}\n\n{LINKEDSERVICEDESC}".format(**context)
    else:
        state = translate_states(context["HOSTSTATE"])
        entity_id = '{HOSTNAME}:{HOSTADDRESS}'.format(**context).replace(" ", "")
        title = '{HOSTNAME} is {HOSTSTATE}'.format(**context)
        text = "{HOSTOUTPUT}\n\n{LINKEDHOSTNAME}".format(**context)
    hostname = context.get('HOSTNAME')

    return {
        "message_type": state,
        "entity_id": entity_id,
        "entity_display_name": title,
        "state_message": text,
        "host_name": hostname,
        "monitoring_tool": "Check_MK notification",
    }


def collect_context():
    # type: () -> Dict
    return {
        var[7:]: value.decode("utf-8")
        for (var, value) in os.environ.items()
        if var.startswith("NOTIFY_")
    }


def retrieve_from_passwordstore(parameter):
    value = parameter.split()

    if len(value) == 2:
        if value[0] == 'store':
            value = cmk.password_store.load().get(value[1])
        else:
            value = value[1]
    else:
        value = value[0]

    return value


def post_request(message_constructor, success_code=200):
    context = collect_context()

    url = retrieve_from_passwordstore(context.get("PARAMETER_WEBHOOK_URL"))

    r = requests.post(url=url, json=message_constructor(context))

    if r.status_code == success_code:
        sys.exit(0)
    else:
        sys.stderr.write(
            "Failed to send notification. Status: %i, Response: %s\n" % (r.status_code, r.text))
        sys.exit(2)


if __name__ == "__main__":
    post_request(victorops_msg)
