import os
import platform
import socket
import httpx
from .config import RunnerConfig
from .device_id import get_device_id
from . import __version__

# Timeout for API requests (30 seconds)
API_TIMEOUT = 30.0


async def validate_token(config: RunnerConfig) -> dict:
    """Validate device token with backend.

    Raises:
        ValueError: If token is not configured or validation fails
        httpx.TimeoutException: If request times out
        httpx.RequestError: If connection fails
    """

    if not config.device_token:
        raise ValueError("Device token not configured")

    # Collect system info — skip deviceId for cloud runners to avoid
    # merge logic destroying the CloudRunner record
    is_cloud = os.getenv("SKOP_CLOUD_RUNNER") == "true"
    device_id = None if is_cloud else get_device_id()
    hostname = socket.gethostname()
    os_platform = platform.system()
    arch = platform.machine()

    payload = {
        "token": config.device_token,
        "version": __version__,
        "hostname": hostname,
        "platform": os_platform,
        "arch": arch,
    }
    if device_id:
        payload["deviceId"] = device_id

    async with httpx.AsyncClient(timeout=API_TIMEOUT) as client:
        response = await client.post(
            f"{config.api_url}/api/runner/register",
            json=payload,
        )

        if response.status_code != 200:
            # Security: Don't include response body in error message
            # as it might echo back the token or contain sensitive info
            raise ValueError(
                f"Token validation failed (HTTP {response.status_code}). "
                "Please check your token and try again."
            )

        return response.json()


def save_token(token: str, config: RunnerConfig):
    """Save device token to config."""
    config.device_token = token
    config.save()
    print(f"Token saved to {config.config_dir / 'config.json'}")
