"""Teleport app listing via tbot (server-side).

In Phase 2, app listing is done server-side using tbot credentials.
App proxy tunneling is deferred to Phase 4.
"""

from __future__ import annotations

import asyncio
import json
import logging

from cube_cloud.teleport.tbot_manager import tbot

logger = logging.getLogger(__name__)


async def app_list(company: str | None = None) -> str:
    """List available Teleport apps using tbot credentials.

    Uses `tctl` or Teleport API via tbot identity to list registered apps.
    Falls back to a curated list if tctl is not available.
    """
    if not tbot.is_ready:
        return "tbot credentials not ready. Server-side app listing is not available yet."

    # Try tsh apps ls with tbot identity
    try:
        cmd = tbot.tsh_base_args() + ["apps", "ls", "--format=json"]
        proc = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
            env=tbot.tsh_env(),
        )
        stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=30)

        if proc.returncode != 0:
            logger.warning("tsh apps ls failed: %s", stderr.decode())
            return f"Failed to list apps: {stderr.decode()}"

        apps = json.loads(stdout.decode())
    except FileNotFoundError:
        return "tsh not found in container. App listing requires tsh to be installed."
    except asyncio.TimeoutError:
        return "App listing timed out."
    except json.JSONDecodeError as e:
        return f"Failed to parse app list: {e}"

    # Filter by company
    if company:
        apps = [
            app for app in apps
            if app.get("metadata", {}).get("labels", {}).get("company", "").lower() == company.lower()
        ]

    if not apps:
        suffix = f" for company '{company}'" if company else ""
        return f"No apps found{suffix}."

    # Group by company
    by_company: dict[str, list] = {}
    for app in apps:
        labels = app.get("metadata", {}).get("labels", {})
        comp = labels.get("company", "unknown")
        by_company.setdefault(comp, []).append(app)

    lines = ["Available Apps:", "=" * 60]
    for comp in sorted(by_company):
        lines.append(f"\n[{comp}]")
        for app in sorted(by_company[comp], key=lambda x: x["metadata"]["name"]):
            name = app["metadata"]["name"]
            spec = app.get("spec", {})
            uri = spec.get("uri", "")
            public_addr = spec.get("public_addr", "")
            app_type = "TCP" if uri.startswith("tcp://") else "HTTP"
            lines.append(f"  {name}")
            lines.append(f"    Type: {app_type}")
            if public_addr:
                lines.append(f"    URL:  https://{public_addr}")

    lines.append("")
    lines.append("Note: App proxy tunneling is available with cube-agent (Phase 4).")
    return "\n".join(lines)
