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


def _is_certificate_check(settings):
    return "cert_days" in settings


def _get_family_and_address(settings):
    # Use the address family of the monitored host by default
    family = settings.get("address_family")
    if family == None:
        family = is_ipv6_primary(host_name()) and "ipv6" or "ipv4"

    if family == "ipv6":
        address = "$_HOSTADDRESS_6$"
    else:
        address = "$_HOSTADDRESS_4$"

    return family, address


def _certificate_args(address_family, address, settings):
    args = []

    if "cert_host" in settings:
        if settings.get('proxy'):
            args += [ '-I', settings['proxy'] ]
            args += [ '-H', settings['cert_host'] ]
            args.append('--ssl')
            args += ['-j', 'CONNECT']
        elif settings.get("sni"):
            args += [ '-H', settings['cert_host'] ]
        else:
            args += [ '-I', settings['cert_host'] ]
            args += [ '-H', address ]
    else:
        args += [ "-I", address ]

    if address_family == 'ipv6':
        args += ['-6']

    if "port" in settings:
        args += [ '-p', settings["port"] ]

    if "proxy_auth" in settings:
        username, password = settings["proxy_auth"]
        args += [ "-b", passwordstore_get_cmdline("%s:%%s" % username, password) ]

    if "cert_days" in settings:
        # legacy behavior
        if type(settings["cert_days"]) == int:
            args += [ '-C', settings["cert_days"] ]
        else:
            warn, crit = settings["cert_days"]
            args += [ '-C', '%d,%d' % (warn, crit) ]

    if "sni" in settings:
        args += ['--sni']

    return args


def _url_args(address_family, address, settings):
    def _omit_ip(settings):
        if "virthost" in settings:
            return settings["virthost"][1]
        return False

    args = []

    if (not _omit_ip(settings)) and ("proxy" not in settings):
        args += [ "-I", address ]
    elif "proxy" in settings:
        args += [ "-I", settings["proxy"] ]

    if "vhost" in settings:
        args += [ "-H", settings["vhost"] ]

    if "virthost" in settings:
        vhost = settings["virthost"][0]
        args += [ "-H", vhost ]

    if address_family == 'ipv6':
        args += ['-6']

    if "port" in settings:
        args += [ '-p', settings["port"] ]

    if "uri" in settings:
        args += [ '-u', settings["uri"] ]

    ssl = settings.get("ssl")
    if ssl in [ True, "auto" ]:
        args += ['--ssl']
    elif ssl:
        args += ['--ssl=%s' % ssl]

    if "sni" in settings:
        args += ['--sni']

    if "response_time" in settings:
        args += [ '-w', '%f' % (settings["response_time"][0]/1000.0),
                  '-c', '%f' % (settings["response_time"][1]/1000.0) ]

    if "timeout" in settings:
        args += [ '-t', settings["timeout"] ]

    if "user_agent" in settings:
        args += [ '-A', settings["user_agent"] ]

    for header in settings.get("add_headers", []):
        args += [ '-k', header ]

    if "auth" in settings:
        username, password = settings["auth"]
        args += [ "-a", passwordstore_get_cmdline("%s:%%s" % username, password) ]

    if "proxy_auth" in settings:
        username, password = settings["proxy_auth"]
        args += [ "-b", passwordstore_get_cmdline("%s:%%s" % username, password) ]

    if "onredirect" in settings:
        args += [ '--onredirect=%s' % settings["onredirect"] ]

    if "expect_response" in settings:
        args += [ '-e', ",".join(settings["expect_response"]) ]

    if "expect_string" in settings:
        args += [ '-s', settings["expect_string"] ]

    if "expect_response_header" in settings:
        args += [ '-d', settings["expect_response_header"] ]

    if "expect_regex" in settings:
        if len(settings['expect_regex']) >= 4 and settings['expect_regex'][3]:
            args += ['-l']
        if settings['expect_regex'][1]:
            args += ['-R']
        else:
            args += ['-r']
        args += [settings['expect_regex'][0]]
        if settings['expect_regex'][2]:
            args += ['--invert-regex']

    if settings.get("extended_perfdata"):
        args += ['--extended-perfdata']

    if "post_data" in settings:
        data, content_type = settings["post_data"]
        args += [ '-P', data, '-T', content_type ]

    if "method" in settings:
        args += [ '-j', settings["method"] ]

    if settings.get("no_body"):
        args += ['--no-body']

    if "page_size" in settings:
        args += [ '-m', '%d:%d' % settings["page_size"] ]

    if "max_age" in settings:
        args += [ '-M', settings["max_age"] ]

    # FIXME: This option is deprecated. According to the monitoring-plugins
    # the "urlize" plugin should be used.
    if settings.get("urlize"):
        args += ['-L']

    if "verbose" in settings:
        args += ["-v"]

    return args


def check_http_arguments(params):
    description, settings = params
    args = []

    address_family, address = _get_family_and_address(settings)

    if _is_certificate_check(settings):
        args += _certificate_args(address_family, address, settings)
    else:
        args += _url_args(address_family, address, settings)

    return args


def check_http_description(params):
    description, settings = params

    if description.startswith("^"):
        return description[1:]

    # here we have to cover connection and certificate checks
    if settings.get("ssl") or settings.get("cert_days"):
        protocol = "HTTPS"
    else:
        protocol = "HTTP"

    return "%s %s" % (protocol, description)


active_check_info['http'] = {
    "command_line"        : '$USER1$/check_http $ARG1$',
    "argument_function"   : check_http_arguments,
    "service_description" : check_http_description,
    "has_perfdata"        : True,
}

