#! /usr/bin/python3 -s
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright contributors to the OpenScanHub project.

import inspect
import os
import socket
import sys
from http.client import HTTPException
from xmlrpc.client import ProtocolError

import kobo.cli
import kobo.client
import kobo.client.commands
import kobo.exceptions

# assuming all commands are in osh/client/commands/cmd_*.py modules
import osh.client.commands
from osh.common.conf import get_config_dict


# inherit container to make sure nobody will change plugins I registered
class OshCommandContainer(kobo.client.ClientCommandContainer):
    pass


def handle_deprecated_options(conf):
    # warn when using deprecated client binary name
    argv0_base = os.path.basename(sys.argv[0])
    if argv0_base == 'covscan':
        print(f"warning: using {argv0_base} executable instead of osh-cli is deprecated!",
              file=sys.stderr)

    def print_warning(opt):
        print(f"warning: forcing {conf[opt]} as {opt}, please update client configuration!",
              file=sys.stderr)

    # xmlrpclib/httplib do not follow HTTP redirect
    if "cov01.lab.eng.brq.redhat.com" in conf["HUB_URL"]:
        conf["HUB_URL"] = "https://cov01.lab.eng.brq2.redhat.com/osh/xmlrpc"
        print_warning("HUB_URL")

    # Handle URL prefix change from `/covscahub` to `/osh` if client has custom configurations
    conf["HUB_URL"] = conf["HUB_URL"].replace("/covscanhub/", "/osh/")

    # there is no 'krbv' for py3 --> use 'gssapi' instead
    if conf["AUTH_METHOD"] == "krbv":
        conf["AUTH_METHOD"] = 'gssapi'
        # TODO: Uncomment in the future.  For now, we should give users some
        # time to settle with the new config files.
        # print_warning("AUTH_METHOD")


def main():
    # register generic kobo commands
    OshCommandContainer.register_module(kobo.client.commands, prefix="cmd_")
    # register project specific commands
    OshCommandContainer.register_module(osh.client.commands, prefix="cmd_")

    conf = get_config_dict(config_env="OSH_CLIENT_CONFIG_FILE",
                           config_default="/etc/osh/client.conf")
    if conf is None:
        sys.exit(2)
    handle_deprecated_options(conf)

    # initialize command container
    command_container = OshCommandContainer(conf)
    parser_args = {
        'command_container': command_container,  # plugin container with registered commands
        'add_username_password_options': True,   # include auth options to each command
    }

    # check that kobo.cli.CommandOptionParser understands the add_hub_option
    sig = inspect.signature(kobo.cli.CommandOptionParser.__init__)
    if 'add_hub_option' in sig.parameters:
        parser_args['add_hub_option'] = True  # include hub option to each command

    parser = kobo.cli.CommandOptionParser(**parser_args)

    try:
        parser.run()
    except kobo.exceptions.ImproperlyConfigured as ex:
        print(f"\n\nError: Improperly configured: {ex}", file=sys.stderr)
        sys.exit(3)
    except (HTTPException, ProtocolError, socket.herror, socket.gaierror, socket.timeout) as ex:
        print(f"\n\nError: {ex}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
