from dataclasses import dataclass
from typing import Union, Dict, Any, Optional


@dataclass
class DtrplOptConfig:
    """Configuration for discrete trust region projection layer optimization.
        Example usages:
        DtrplOptConfig(num_points=32, max_steps=30, x_threshold=1e-5, lower=1e-5, upper=1e5)
        DtrplOptConfig.from_dict({"num_points": 32, "max_steps": 30, "x_threshold": 1e-5, "lower": 1e-5, "upper": 1e5})
        DtrplOptConfig(**cfg_dict) where cfg_dict is a dictionary with the appropriate keys.
        DtrplOptConfig.from_dict(cfg_dict)  # Returns default configuration
    """
    num_points: int = 8
    max_steps: int = 50
    x_threshold: float = 1e-7
    lower: float = 1e-12
    upper: float = 1e12

    @classmethod
    def from_dict(cls, opt_cfg: Optional[Union['DtrplOptConfig', Dict[str, Any]]]) -> 'DtrplOptConfig':
        """
        Create a DtrplOptConfig instance from various input types.

        Args:
            opt_cfg: None, DtrplOptConfig instance, or dict of parameters

        Returns:
            DtrplOptConfig instance
        """
        if opt_cfg is None:
            return cls()
        elif isinstance(opt_cfg, dict):
            return cls(**opt_cfg)
        elif isinstance(opt_cfg, cls):
            return opt_cfg
        else:
            raise TypeError(f"opt_cfg must be a {cls.__name__} instance, dict, or None. Got: {type(opt_cfg)}")

