"""
automl_lib.callbacks
~~~~~~~~~~~~~~~~~~~~
Pluggable callbacks for custom training logic.
"""

from __future__ import annotations

from typing import Any, Dict

class Callback:
    """Base class for all callbacks."""
    def on_train_begin(self, config: Any): pass
    def on_train_end(self, history: Dict[str, list[float]]): pass
    def on_epoch_begin(self, epoch: int): pass
    def on_epoch_end(self, epoch: int, metrics: Dict[str, float]): pass
    def on_batch_begin(self, batch: int): pass
    def on_batch_end(self, batch: int, loss: float): pass

class CallbackList:
    """Container for managing multiple callbacks."""
    def __init__(self, callbacks: list[Callback] | None = None):
        self.callbacks = callbacks or []

    def on_train_begin(self, config: Any):
        for c in self.callbacks: c.on_train_begin(config)
    
    def on_train_end(self, history: Dict[str, list[float]]):
        for c in self.callbacks: c.on_train_end(history)

    def on_epoch_begin(self, epoch: int):
        for c in self.callbacks: c.on_epoch_begin(epoch)

    def on_epoch_end(self, epoch: int, metrics: Dict[str, float]):
        for c in self.callbacks: c.on_epoch_end(epoch, metrics)

    def on_batch_begin(self, batch: int):
        for c in self.callbacks: c.on_batch_begin(batch)

    def on_batch_end(self, batch: int, loss: float):
        for c in self.callbacks: c.on_batch_end(batch, loss)
