#!/usr/bin/env python3
"""
Send a result to syslog.
"""

import pscheduler
import sys
import syslog

MAX_SCHEMA = 1

FACILITIES = {
    'kern': syslog.LOG_KERN,
    'user': syslog.LOG_USER,
    'mail': syslog.LOG_MAIL,
    'daemon': syslog.LOG_DAEMON,
    'auth': syslog.LOG_AUTH,
    'lpr': syslog.LOG_LPR,
    'news': syslog.LOG_NEWS,
    'uucp': syslog.LOG_UUCP,
    'cron': syslog.LOG_CRON,
    'syslog': syslog.LOG_SYSLOG,
    'local0': syslog.LOG_LOCAL0,
    'local1': syslog.LOG_LOCAL1,
    'local2': syslog.LOG_LOCAL2,
    'local3': syslog.LOG_LOCAL3,
    'local4': syslog.LOG_LOCAL4,
    'local5': syslog.LOG_LOCAL5,
    'local6': syslog.LOG_LOCAL6,
    'local7': syslog.LOG_LOCAL7
    }


PRIORITIES = {
    'emerg': syslog.LOG_EMERG,
    'alert': syslog.LOG_ALERT,
    'crit': syslog.LOG_CRIT,
    'err': syslog.LOG_ERR,
    'warning': syslog.LOG_WARNING,
    'notice': syslog.LOG_NOTICE,
    'info': syslog.LOG_INFO,
    'debug': syslog.LOG_DEBUG
    }


log = pscheduler.Log(name="syslog-archiver")

def archive(json):

    log.debug("Archiving %s" % (json))

    errors = ()

    schema = json["data"].get("schema", 1)
    if schema > MAX_SCHEMA:
        return {
            "succeeded": False,
            "error": "Unsupported schema version %d; max is %d" % (
                schema, MAX_SCHEMA)
        }

    # Ident

    try:
        ident = json['data']['ident']
    except KeyError:
        ident = 'pScheduler'

    # Facility

    try:
        facility_str = json['data']['facility']
    except KeyError:
        facility_str = 'user'
    try:
        facility = FACILITIES[facility_str]
    except KeyError:
        errors.append("Invalid facility")

    # Priority

    try:
        priority_str = json['data']['priority']
    except KeyError:
        priority_str = 'info'
    try:
        priority = PRIORITIES[priority_str]
    except KeyError:
        errors.append("Invalid priority '%s'" % priority_str)

    if errors:
        return {
            "succeeded": False,
            "error": '; '.join(errors)
        }

    # Log the run

    log.debug("Ident %s, Facility %d" % (ident, facility))
    try:
        # Ident often comes in unicode and this requires a string.
        syslog.openlog(str(ident), 0, facility)

        result = json['result']
        if isinstance(result, str):
            # Post strings cleanly
            output = result
        else:
            # Anything else is JSON
            output = pscheduler.json_dump(json['result'])
        syslog.syslog(priority, output)
        syslog.closelog()
    except Exception as ex:
        log.debug("Failed: %s" % (str(ex)))
        return {
            "succeeded": False,
            "error": "Failed to log result: %s" % str(ex)
        }

    log.debug("Succeeded")
    return {'succeeded': True}




PARSER = pscheduler.RFC7464Parser(sys.stdin)
EMITTER = pscheduler.RFC7464Emitter(sys.stdout)

for parsed in PARSER:
    try:
        EMITTER(archive(parsed))
    except BrokenPipeError as ex:
        log.warning("Broken pipe during archiving; parent must have exited.")
        pscheduler.succeed()

pscheduler.succeed()
