#!/usr/bin/env python3
"""
Structured JSON logging for Turf SaaS.
Replaces default Flask/Python logging with JSON output suitable for log aggregation.
"""

import logging
import sys
import os
import json
import traceback
from datetime import datetime, timezone
from typing import Optional


class JSONFormatter(logging.Formatter):
    """Format log records as JSON lines."""

    def __init__(self, service_name: str = "turf-saas", env: str = "production"):
        super().__init__()
        self.service_name = service_name
        self.env = env

    def format(self, record: logging.LogRecord) -> str:
        log_entry = {
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "level": record.levelname,
            "service": self.service_name,
            "env": self.env,
            "logger": record.name,
            "message": record.getMessage(),
            "module": record.module,
            "function": record.funcName,
            "line": record.lineno,
        }

        # Add extra fields if present
        if hasattr(record, "request_id"):
            log_entry["request_id"] = record.request_id
        if hasattr(record, "user_id"):
            log_entry["user_id"] = record.user_id
        if hasattr(record, "duration_ms"):
            log_entry["duration_ms"] = record.duration_ms
        if hasattr(record, "status_code"):
            log_entry["status_code"] = record.status_code
        if hasattr(record, "endpoint"):
            log_entry["endpoint"] = record.endpoint

        # Exception info
        if record.exc_info:
            log_entry["exception"] = {
                "type": record.exc_info[0].__name__ if record.exc_info[0] else None,
                "message": str(record.exc_info[1]) if record.exc_info[1] else None,
                "traceback": traceback.format_exception(*record.exc_info),
            }

        return json.dumps(log_entry, ensure_ascii=False)


def setup_logging(
    service_name: str = "turf-saas",
    level: Optional[str] = None,
    use_json: bool = True,
) -> logging.Logger:
    """
    Configure root logger with JSON or plain formatting.

    Args:
        service_name: Service name embedded in each log record.
        level: Log level (default: from LOG_LEVEL env var, fallback INFO).
        use_json: Use JSON formatter (True in production, False in dev).

    Returns:
        Root logger.
    """
    log_level = level or os.environ.get("LOG_LEVEL", "INFO")
    env = os.environ.get("FLASK_ENV", "production")

    # Force plain text in dev/testing
    if env in ("development", "testing"):
        use_json = False

    root_logger = logging.getLogger()
    root_logger.setLevel(getattr(logging, log_level.upper(), logging.INFO))

    # Remove existing handlers
    root_logger.handlers.clear()

    handler = logging.StreamHandler(sys.stdout)

    if use_json:
        handler.setFormatter(JSONFormatter(service_name=service_name, env=env))
    else:
        handler.setFormatter(
            logging.Formatter(
                fmt="%(asctime)s [%(levelname)s] %(name)s — %(message)s",
                datefmt="%Y-%m-%d %H:%M:%S",
            )
        )

    root_logger.addHandler(handler)

    # Silence noisy third-party loggers
    for noisy in ["werkzeug", "urllib3", "requests", "gunicorn.access"]:
        logging.getLogger(noisy).setLevel(logging.WARNING)

    return root_logger


def get_logger(name: str) -> logging.Logger:
    """Get a named logger."""
    return logging.getLogger(name)
