"""Authentication and agent registration.

Internal module used by install.sh for agent registration.
Not intended for direct user use.
"""

import logging
import sys
import os
import time
import platform
import socket
import requests
from typing import Optional
from runsentry.config import get_config, CONFIG_PATH

logger = logging.getLogger(__name__)


def register_agent(token: str, backend_url: str, agent_name: Optional[str] = None, retries: int = 3, retry_delay: int = 5) -> bool:
    """
    Register agent with RunSentry backend.
    
    Internal function used by install.sh. Handles registration with retries
    and saves configuration.
    
    Args:
        token: Registration token (required)
        backend_url: Backend URL (required)
        agent_name: Agent name (optional, defaults to hostname)
        retries: Number of registration retry attempts (default: 3)
        retry_delay: Delay between retries in seconds (default: 5)
    
    Returns:
        True if registration successful, False otherwise
    """
    if not token:
        logger.error("Registration token is required")
        return False
    
    if not backend_url:
        logger.error("Backend URL is required")
        return False
    
    config = get_config()
    
    # Check if already configured (idempotency)
    if config.is_configured():
        logger.info(f"Agent is already configured (ID: {config.agent_id})")
        return True
    
    # Detect agent name if not provided
    if not agent_name:
        agent_name = os.environ.get("RUNSENTRY_AGENT_NAME") or socket.gethostname()
    
    # Detect host information
    hostname = socket.gethostname()
    os_name = platform.system().lower()
    arch = platform.machine()
    
    # Detect agent type
    agent_type = "linux-cron"
    if os.path.exists("/var/run/secrets/kubernetes.io"):
        agent_type = "kubernetes"
    
    payload = {
        "agentName": agent_name,
        "agentType": agent_type,
        "version": "1.0.0",
        "host": {
            "hostname": hostname,
            "os": os_name,
            "arch": arch,
        },
    }
    
    # Retry logic for registration
    logger.info(f"Registering agent with backend: {backend_url}")
    logger.info(f"Agent name: {agent_name}")
    
    for attempt in range(1, retries + 1):
        try:
            response = requests.post(
                f"{backend_url}/api/v1/agents/register",
                json=payload,
                headers={
                    "Content-Type": "application/json",
                    "X-Registration-Token": token,
                },
                timeout=30,
            )
            response.raise_for_status()
            
            data = response.json()
            agent_id = data.get("agentId")
            agent_token = data.get("token")  # Non-expiring token for all API calls
            workspace_id = data.get("workspaceId")
            backend_url_from_response = data.get("backendUrl", backend_url)
            
            if not agent_id or not agent_token:
                raise ValueError("Invalid response from backend: missing agentId or token")
            
            # Save configuration
            config.agent_id = agent_id
            config.token = agent_token  # This token never expires, use for all API calls
            config.backend_url = backend_url_from_response  # Use backend URL from response
            config.agent_name = agent_name
            if workspace_id:
                config.workspace_id = workspace_id
            config.save()
            
            logger.info(f"Successfully registered agent: {agent_name} ({agent_id})")
            logger.info(f"Configuration saved to {CONFIG_PATH}")
            
            return True
            
        except requests.exceptions.RequestException as e:
            if attempt < retries:
                logger.warning(f"Registration attempt {attempt}/{retries} failed: {e}")
                logger.info(f"Retrying in {retry_delay} seconds...")
                time.sleep(retry_delay)
            else:
                logger.error(f"Failed to register agent after {retries} attempts")
                if hasattr(e, "response") and e.response is not None:
                    try:
                        error_data = e.response.json()
                        logger.error(f"Backend error: {error_data}")
                    except:
                        logger.error(f"Response: {e.response.text}")
                else:
                    logger.error(f"Error details: {e}")
            continue
        except Exception as e:
            logger.error(f"Unexpected error during registration: {e}", exc_info=True)
            if attempt < retries:
                time.sleep(retry_delay)
            continue
    
    return False

