"""Webhook web server."""
import logging
import platform
import time
from queue import Queue
from eth_defi.utils import is_localhost_port_listening
import warnings
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    from webtest.http import StopableWSGIServer
from .app import create_pyramid_app
from ..state.metadata import Metadata
from ..state.store import JSONFileStore
from ..strategy.run_state import RunState
logger =  logging.getLogger(__name__)
[docs]class WebhookServer(StopableWSGIServer):
    """Create a Waitress server that we can gracefully shut down.
    https://docs.pylonsproject.org/projects/waitress/en/latest/
    """
[docs]    def shutdown(self, wait_gracefully=3.0):
        super().shutdown()
        # Check that the server gets shut down.
        # Looks like this is being an issue on Github CI.
        port = int(self.effective_port)
        logger.info("Shutting down %s: %d", self.effective_host, port)
        # is_localhost_port_listening seems to never free up port on Mac M1
        if platform.mac_ver()[0]:
            time.sleep(0.25)
            return
        deadline = time.time() + wait_gracefully
        while time.time() < deadline:
            if not is_localhost_port_listening(host=self.effective_host, port=port):
                return
            time.sleep(1)
        raise AssertionError(f"Could not gracefully shut down {self.effective_host}:{port}, waited {wait_gracefully} seconds")  
[docs]def create_webhook_server(
        host: str,
        port: int,
        username: str,
        password: str,
        queue: Queue,
        store: JSONFileStore,
        metadata: Metadata,
        execution_state: RunState,
) -> WebhookServer:
    """Starts the webhook web  server in a separate thread.
    :param queue: The command queue for commands posted in the webhook that offers async execution.
    """
    app = create_pyramid_app(username, password, queue, store, metadata, execution_state, production=False)
    server = WebhookServer.create(app, host=host, port=port, clear_untrusted_proxy_headers=True)
    logger.info("Webhook server will spawn at %s:%d, using username %s", host, port, username)
    # Wait until the server has started
    server.wait()
    return server