"""Gravity Control — Antigravity Discord Bridge.

Entry point that runs the brain watcher and Discord bot together.
"""

import asyncio
import io
import logging
import os
import sys

from config import Config
from bot import GravityBot

# Logging setup (UTF-8 forced for Windows cp949 compatibility)
_utf8_stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    handlers=[
        logging.StreamHandler(_utf8_stdout),
        logging.FileHandler("gravity_control.log", encoding="utf-8"),
    ],
)
logger = logging.getLogger("gravity_control")


async def main():
    """Run the bridge: watcher + Discord bot."""

    # Validate config
    errors = Config.validate()
    if errors:
        for e in errors:
            logger.error(f"Config error: {e}")
        logger.error("Fix configuration issues and restart.")
        sys.exit(1)

    logger.info("=" * 50)
    logger.info("Gravity Control — Antigravity Discord Bridge")
    logger.info("=" * 50)
    logger.info(f"Brain path: {Config.BRAIN_PATH}")
    logger.info(f"Debounce: {Config.DEBOUNCE_SECONDS}s")
    logger.info(f"Bot mode: {Config.BOT_MODE}")

    # Shared event queue
    event_queue = asyncio.Queue()

    # Get the running loop
    loop = asyncio.get_running_loop()

    # Create components
    bot = GravityBot(event_queue)

    try:
        # Start Gateway HTTP API + WebSocket Hub
        from gateway import GatewayAPI
        from hub import WSHub
        from auth import TokenManager

        # Initialize Hub
        token_mgr = TokenManager(
            secret=Config.GRAVITY_HUB_SECRET,
            registration_code=Config.GRAVITY_REGISTRATION_CODE,
        )
        hub = WSHub(token_mgr)

        gateway_port = int(os.environ.get('GATEWAY_PORT', '8585'))
        gateway = GatewayAPI(
            bot, port=gateway_port,
            api_key=Config.GATEWAY_API_KEY,
            hub=hub,
        )
        bot.gateway = gateway  # Enable _write_command → gateway.push_command
        bot.hub = hub          # Enable Hub-based message routing
        await gateway.start()
        logger.info(f"Gateway API + WS Hub running on port {gateway_port}")

        # Run Discord bot (blocks until bot disconnects)
        await bot.start(Config.DISCORD_TOKEN)

    except KeyboardInterrupt:
        logger.info("Received keyboard interrupt")
    except Exception as e:
        logger.error(f"Fatal error: {e}", exc_info=True)
    finally:
        # Cleanup
        if not bot.is_closed():
            await bot.close()
        logger.info("Gravity Control shutdown complete")


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass
