#!/usr/bin/python3.6 -s
"""
Wrapper for cobbler's remote syslog watching daemon.
"""

# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: Copyright 2006-2009, Red Hat, Inc and Others
# SPDX-FileCopyrightText: Michael DeHaan <michael.dehaan AT gmail>

import argparse
import logging
import os
import sys
import traceback

import cobbler.api as cobbler_api
import cobbler.cobblerd as app

logger = logging.getLogger()


def daemonize_self():
    # daemonizing code:  http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
    logger.info("cobblerd started")
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as e:
        print("fork #1 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr)
        sys.exit(1)

    # decouple from parent environment
    os.chdir("/")
    os.setsid()
    os.umask(0o22)

    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # print "Daemon PID %d" % pid
            sys.exit(0)
    except OSError as e:
        print("fork #2 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr)
        sys.exit(1)

    with open("/dev/null", "r+") as dev_null:
        os.dup2(dev_null.fileno(), sys.stdin.fileno())
        os.dup2(dev_null.fileno(), sys.stdout.fileno())
        os.dup2(dev_null.fileno(), sys.stderr.fileno())


def main() -> int:
    op = argparse.ArgumentParser()
    op.set_defaults(daemonize=True, log_level=None)
    op.add_argument(
        "-B",
        "--daemonize",
        dest="daemonize",
        action="store_true",
        help="run in background (default)",
    )
    op.add_argument(
        "-F",
        "--no-daemonize",
        dest="daemonize",
        action="store_false",
        help="run in foreground (do not daemonize)",
    )
    op.add_argument(
        "-f", "--log-file", dest="log_file", metavar="NAME", help="file to log to"
    )
    op.add_argument(
        "-l",
        "--log-level",
        dest="log_level",
        metavar="LEVEL",
        help="log level (ie. INFO, WARNING, ERROR, CRITICAL)",
    )
    op.add_argument(
        "--config",
        "-c",
        help="The location of the Cobbler configuration file.",
        default="/etc/cobbler/settings.yaml",
    )
    op.add_argument(
        "--enable-automigration",
        help='If given, overrule setting from "settings.yaml" and execute automigration.',
        dest="automigration",
        action="store_true",
    )
    op.add_argument(
        "--disable-automigration",
        help='If given, overrule setting from "settings.yaml" and do not execute automigration.',
        dest="automigration",
        action="store_false",
    )
    op.set_defaults(automigration=None)

    options = op.parse_args()

    # load the API now rather than later, to ensure cobblerd
    # startup time is done before the service returns
    api = None
    try:
        api = cobbler_api.CobblerAPI(
            is_cobblerd=True,
            settingsfile_location=options.config,
            execute_settings_automigration=options.automigration,
        )
    except Exception as exc:
        if sys.exc_info()[0] == SystemExit:
            return exc.code
        else:
            # FIXME: log this too
            traceback.print_exc()
            return 1

    if options.daemonize:
        daemonize_self()

    try:
        app.core(api)
    except Exception as e:
        logger.error(e)
        traceback.print_exc()


if __name__ == "__main__":
    sys.exit(main())
