import os
import sys
import click
import traceback

from wurker.settings import conf
from wurker.cli.base import CommandNotReady

from .command import ServiceCommand


def register_service_command(admin):

    virtualenv = os.path.dirname(os.path.dirname(sys.executable))
    socket = os.path.join("/tmp", "wurker-ui.sock")
    domain_help = (
        f"default: '{conf.domain}'" if conf.domain
        else f"example: 'queen.example.com'"
    )

    ssl_dir = os.path.join(conf.etc_root, 'nginx', 'ssl')
    ssl_certs = ('wurker.crt', 'wurker.key')


    @admin.group('service')
    @click.pass_context
    def service(ctx):
        """Configure Wurker services"""
        pass


    @service.command()
    @click.option("--virtualenv", default=virtualenv,
                  help=f"Root path of the Python venv to use (default: '{virtualenv}')")
    @click.option("--workingdir", default=conf.conf_root,
                  help=f"Working directory for 'wurker' service (default: '{conf.conf_root}')")
    @click.pass_context
    def wurker(ctx, virtualenv, workingdir):
        """Configure Wurker service"""

        try:
            logger = ctx.obj.get("logger")
            cmd = ServiceCommand(logger=logger)
            cmd.run("wurker", virtualenv=virtualenv, workingdir=workingdir)
        except CommandNotReady as ex:
            if conf.debug:
                click.echo(traceback.format_exc(), err=True)
            raise click.ClickException(
                f"The 'wurk admin service wurker' command is not ready. Run 'wurk admin --help'. {ex}"
            )
        except Exception as ex:
            if conf.debug:
                click.echo(traceback.format_exc(), err=True)
            raise click.ClickException(str(ex))


    @service.command()
    @click.option("--virtualenv", default=virtualenv,
                  help=f"Root path of the Python venv to use (default: '{virtualenv}')")
    @click.option("--workingdir", default=conf.conf_root,
                  help=f"Working directory for 'wurker-ui' service (default: '{conf.conf_root}')")
    @click.option("--domain", default=conf.domain,
                  help=f"Domain name for 'wurker-ui' virtual host ({domain_help})")
    @click.option("--workers", default=conf.workers,
                  help=f"Number of webserver workers (default: {conf.workers}')")
    @click.option("--socket", default=socket,
                  help=f"Path to unix socket for 'wurker-ui' (default: '{socket}')")
    @click.option("--ssl-dir", default=ssl_dir,
                  help=f"Path to Nginx SSL certs for 'wurker-ui' (default: '{ssl_dir}')")
    @click.option("--ssl-certs", type=(str, str), default=ssl_certs, metavar="CRT KEY",
                  help=f"Names of SSL certs for 'wurker-ui' (default: {ssl_certs})")
    @click.pass_context
    def ui(ctx, virtualenv, workingdir, domain, workers, socket, ssl_dir, ssl_certs):
        """Configure Wurker UI service and Nginx config"""

        try:
            logger = ctx.obj.get("logger")
            cmd = ServiceCommand(logger=logger)
            cmd.run(
                "ui",
                virtualenv=virtualenv,
                workingdir=workingdir,
                domain=domain,
                workers=workers,
                socket=socket,
                ssl_dir=ssl_dir,
                ssl_certs=ssl_certs,
            )

        except CommandNotReady as ex:
            if conf.debug:
                click.echo(traceback.format_exc(), err=True)
            raise click.ClickException(
                f"The 'wurk admin service ui' command is not ready. Run 'wurk admin --help'. {ex}"
            )
        except Exception as ex:
            if conf.debug:
                click.echo(traceback.format_exc(), err=True)
            raise click.ClickException(str(ex))
