"""
Base model factory class that all specific model factories should inherit from.
"""
from abc import ABC, abstractmethod
import mlflow

class BaseModelFactory(ABC):
    """
    Abstract base class for model factories.
    """
    
    def __init__(self, config=None):
        """
        Initialize the model factory.
        
        Parameters
        ----------
        config : dict, optional
            Configuration dictionary
        """
        self.config = config or {}
    
    @abstractmethod
    def create_model(self, config=None):
        """
        Create a model based on configuration.
        
        Parameters
        ----------
        config : dict, optional
            Configuration dictionary
        
        Returns
        -------
        model
            Created model instance
        """
        pass
    
    @abstractmethod
    def compile_model(self, model, config=None):
        """
        Compile a model with appropriate optimizer, loss, and metrics.
        
        Parameters
        ----------
        model : model instance
            Model to compile
        config : dict, optional
            Configuration dictionary
        
        Returns
        -------
        model
            Compiled model instance
        """
        pass
    
    @abstractmethod
    def train_model(self, model, train_generator, validation_generator, config=None):
        """
        Train a model with the given generators.
        
        Parameters
        ----------
        model : model instance
            Model to train
        train_generator : BaseDataGenerator
            Training data generator
        validation_generator : BaseDataGenerator
            Validation data generator
        config : dict, optional
            Configuration dictionary
        
        Returns
        -------
        history
            Training history
        """
        pass
    
    def autolog(self):
        """
        Configure automatic logging.
        """
        pass
    
    def evaluate(self, model, test_generator):
        """
        Evaluate a model with the given test data.
        
        Parameters
        ----------
        model : model instance
            Model to evaluate
        test_generator : BaseDataGenerator
            Test data generator
        
        Returns
        -------
        dict
            Evaluation results
        """
        pass
    
    def predict(self, model, test_generator):
        """
        Generate predictions with the model.
        
        Parameters
        ----------
        model : model instance
            Model to use for prediction
        test_generator : BaseDataGenerator
            Test data generator
        
        Returns
        -------
        array
            Predictions
        """
        pass