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

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

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

import typer
from fastapi import FastAPI

from .application import FastKafka
from ._components.logger import get_logger, supress_timestamps
from ._components.helpers import _import_from_string
from fastkafka.server import (
    run_fastkafka_server,
    terminate_asyncio_process,
    run_in_process,
)
from ._components.asyncapi import _install_deps

from .testing import change_dir

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

# %% ../nbs/004_CLI.ipynb 8
_app = typer.Typer(help="")
_run_app = typer.Typer(help="")
# _app.add_typer(_run_app, name="run")
_docs_app = typer.Typer(
    help="Collection of functions for managing fastkafka app documentation"
)
_app.add_typer(_docs_app, name="docs")


@_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/004_CLI.ipynb 12
@_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)
