"""
automl_lib.utils
~~~~~~~~~~~~~~~~
Shared helpers: logging, seed setting, path utilities, timer.
"""

import logging
import os
import random
import time
from contextlib import contextmanager

import numpy as np


def get_logger(name: str = "automl_lib", level: int = logging.INFO) -> logging.Logger:
    """Return a configured logger with console handler."""
    logger = logging.getLogger(name)
    if not logger.handlers:
        logger.propagate = False
        handler = logging.StreamHandler()
        formatter = logging.Formatter(
            "[%(asctime)s] %(levelname)s - %(name)s - %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    logger.setLevel(level)
    return logger


def set_seed(seed: int = 42):
    """Set random seed for reproducibility across numpy, random, and torch."""
    random.seed(seed)
    np.random.seed(seed)
    try:
        import torch
        torch.manual_seed(seed)
        if torch.cuda.is_available():
            torch.cuda.manual_seed_all(seed)
            torch.backends.cudnn.deterministic = True
            torch.backends.cudnn.benchmark = False
    except ImportError:
        pass


def ensure_dir(path: str) -> str:
    """Create directory if it doesn't exist; return the path."""
    os.makedirs(path, exist_ok=True)
    return path


@contextmanager
def timer(label: str = "Block"):
    """Context manager that logs elapsed time."""
    logger = get_logger()
    start = time.perf_counter()
    logger.info(f"{label} started")
    yield
    elapsed = time.perf_counter() - start
    logger.info(f"{label} finished in {elapsed:.2f}s")


def file_extension(path: str) -> str:
    """Return lowercase file extension without the dot."""
    return os.path.splitext(path)[1].lower().lstrip(".")


def list_files(directory: str, extensions: list[str] | None = None) -> list[str]:
    """Recursively list files in *directory*, optionally filtered by extension."""
    matched = []
    for root, _, files in os.walk(directory):
        for f in files:
            if extensions is None or file_extension(f) in extensions:
                matched.append(os.path.join(root, f))
    return sorted(matched)
