# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/023_CLI.ipynb.

# %% auto 0
__all__ = ['logger', 'run', 'install_deps', 'generate_docs', 'serve_docs']

# %% ../nbs/023_CLI.ipynb 1
import asyncio
import copy
import importlib
import multiprocessing
import signal
import socketserver
import sys
import threading
import time
from contextlib import contextmanager
from http.server import HTTPServer, SimpleHTTPRequestHandler
from os import getpid
from pathlib import Path
from types import FrameType
from typing import *

import anyio
import typer

from ._components.asyncapi import _install_deps
from ._components.helpers import _import_from_string, change_dir
from ._components.logger import get_logger, supress_timestamps
from . import FastKafka
from fastkafka._server import (
    run_fastkafka_server,
    terminate_asyncio_process,
)
from ._testing.local_broker import LocalKafkaBroker

# %% ../nbs/023_CLI.ipynb 5
logger = get_logger(__name__)

# %% ../nbs/023_CLI.ipynb 8
_app = typer.Typer(help="")

# _run_app = typer.Typer(help="")
# _app.add_typer(_run_app, name="run")
_docs_app = typer.Typer(help="Commands for managing fastkafka app documentation")
_app.add_typer(_docs_app, name="docs")

# %% ../nbs/023_CLI.ipynb 9
@_app.command(
    help="Runs Fast Kafka API application",
)
def run(
    num_workers: int = typer.Option(
        multiprocessing.cpu_count(),
        help="Number of FastKafka instances to run, defaults to number of CPU cores.",
    ),
    app: str = typer.Argument(
        ...,
        help="input in the form of 'path:app', where **path** is the path to a python file and **app** is an object of type **FastKafka**.",
    ),
) -> None:
    try:
        asyncio.run(run_fastkafka_server(num_workers=num_workers, app=app))
    except Exception as e:
        typer.secho(f"Unexpected internal error: {e}", err=True, fg=typer.colors.RED)
        raise typer.Exit(1)

# %% ../nbs/023_CLI.ipynb 13
@_docs_app.command(
    "install_deps",
    help="Creates documentation for a Fast Kafka API application ",
)
def install_deps() -> None:
    try:
        _install_deps()
    except Exception as e:
        typer.secho(f"Unexpected internal error: {e}", err=True, fg=typer.colors.RED)
        raise typer.Exit(1)


@_docs_app.command(
    "generate",
    help="Creates documentation for a Fast Kafka API application ",
)
def generate_docs(
    root_path: str = typer.Option(
        ".", help="root path under which documentation will be created"
    ),
    app: str = typer.Argument(
        ...,
        help="input in the form of 'path:app', where **path** is the path to a python file and **app** is an object of type **FastKafka**.",
    ),
) -> None:
    try:
        application = _import_from_string(app)
        application.skip_docs = False
        application.create_docs()
    except Exception as e:
        typer.secho(f"Unexpected internal error: {e}", err=True, fg=typer.colors.RED)
        raise typer.Exit(1)


@_docs_app.command(
    "serve",
    help="Creates documentation for a Fast Kafka API application ",
)
def serve_docs(
    root_path: str = typer.Option(
        ".", help="root path under which documentation will be created"
    ),
    bind: str = typer.Option("127.0.0.1", help="Some info"),
    port: int = typer.Option(8000, help="Some info"),
    app: str = typer.Argument(
        ...,
        help="input in the form of 'path:app', where **path** is the path to a python file and **app** is an object of type **FastKafka**.",
    ),
) -> None:
    try:
        application = _import_from_string(app)
        application.create_docs()
        with change_dir("asyncapi/docs/"):
            server_address = (bind, port)
            handler = SimpleHTTPRequestHandler

            # httpd = HTTPServer(server_address, handler)

            d = {"should_stop": False}

            def sigint_handler(
                signal: int, frame: Optional[FrameType], d: Dict[str, bool] = d
            ) -> None:
                d["should_stop"] = True

            signal.signal(signal.SIGINT, sigint_handler)
            signal.signal(signal.SIGTERM, sigint_handler)

            with socketserver.TCPServer(server_address, handler) as httpd:
                httpd.timeout = 0.1
                typer.secho(
                    f"Serving documentation on http://{server_address[0]}:{server_address[1]}"
                )
                while not d["should_stop"]:
                    httpd.handle_request()
                typer.secho(f"Interupting serving of documentation and cleaning up...")
    except Exception as e:
        typer.secho(f"Unexpected internal error: {e}", err=True, fg=typer.colors.RED)
        raise typer.Exit(1)
