from __future__ import annotations

import json
import subprocess

from fastapi import APIRouter, Request
from pydantic import BaseModel

from remotivelabs.cli.settings import settings
from remotivelabs.cli.topology.cli.topology_cli import run_topology
from remotivelabs.cli.utils import versions

router = APIRouter(prefix="/api/studio/v1/environment", tags=["environment"])


class VersionInfo(BaseModel):
    name: str
    version: str


class EnvironmentResponse(BaseModel):
    workspace: str
    broker_url: str
    auth_mode: str | None
    versions: list[VersionInfo]


class TopologyVersionInfo:
    """Parsed version information from topology --version output."""

    def __init__(self, topology: str | None = None, broker: str | None = None):
        self.versions = [
            VersionInfo(name="RemotiveTopology", version=topology or "unknown"),
            VersionInfo(name="Default RemotiveBroker", version=broker or "unknown"),
        ]


def parse_topology_version_output(output: str) -> TopologyVersionInfo:
    """Parse the "topology --version" output to extract version information. This output format is only
    received when running with the REMOTIVE_STUDIO environment variable set.

    Example output:
        {"topology_cli_version":"0.19.0-21-gcc17cc2c","default_remotivebroker_version":"1.17.0"}
    """
    try:
        data = json.loads(output.strip())
        return TopologyVersionInfo(
            topology=data.get("topology_cli_version"),
            broker=data.get("default_remotivebroker_version"),
        )
    except (json.JSONDecodeError, TypeError):
        return TopologyVersionInfo()


def get_cli_version_info() -> VersionInfo:
    return VersionInfo(name="RemotiveCLI", version=versions.cli_version())


def get_topology_version_info(request: Request) -> TopologyVersionInfo:
    """Get version info from remotive-topology by running the CLI command."""
    try:
        ctx = request.app.state.topology
        result = run_topology(ctx, ["--version"], capture_output=True)
        return parse_topology_version_output(result.stdout)
    except (subprocess.CalledProcessError, Exception):
        return TopologyVersionInfo()


def get_auth_mode() -> str | None:
    if settings.get_active_token():
        return "token"
    return None


def get_versions(request: Request) -> list[VersionInfo]:
    """Return version information for RemotiveCLI, RemotiveTopology, and RemotiveBroker."""
    topology_version_info = get_topology_version_info(request)
    return [
        get_cli_version_info(),
        topology_version_info.versions[0],
        topology_version_info.versions[1],
    ]


@router.get("")
def environment(request: Request) -> EnvironmentResponse:
    return EnvironmentResponse(
        workspace=str(request.app.state.topology.workspace),
        broker_url=str(request.app.state.broker_url),
        auth_mode=get_auth_mode(),
        versions=get_versions(request),
    )
