"""
config.py — Hyperparameters for the Raman-spectroscopy domain-adaptation study.
"""

HYPERPARAMETERS = {
    # ── Optimizer ──────────────────────────────────────────────
    'lr': 1e-3,
    'weight_decay': 1e-4,

    # ── Training ───────────────────────────────────────────────
    'batch_size': 128,
    'epochs': 30,
    'gradient_clip_norm': 1.0,

    # ── Model ───────────────────────────────────────────────────
    'hidden_dim': 256,
    'num_classes': 10,

    # ── Strategy weights ───────────────────────────────────────
    'lambda_domain': 0.5,    # DANN / CORAL domain-adversarial weight
    'lambda_selfsup': 0.3,   # Raman self-supervised reconstruction weight

    # ── Domain-shift simulation ───────────────────────────────
    'source_ratio': 0.5,     # fraction of classes in source domain
    'target_noise_std': 0.1, # Gaussian noise σ on target images (Raman proxy)

    # ── Self-supervised masking ───────────────────────────────
    'mask_ratio': 0.4,       # fraction of pseudo-spectrum masked

    # ── Reproducibility ───────────────────────────────────────
    'seed': 42,
    'seeds': [0, 1, 2],      # fixed minimum 3 seeds
    'num_workers': 2,
    'pin_memory': False,

    # ── Experiment budget ──────────────────────────────────────
    'time_budget_seconds': 270,  # 80 % of 300 s guard
    'time_budget_minutes': 4.5,
    'quality_threshold': 4.0,   # dummy — primary_metric is 0-1 accuracy

    # ── Device ─────────────────────────────────────────────────
    'device': 'cpu',
}


class Config:
    """Picklable config object backed by HYPERPARAMETERS dict."""

    def __init__(self, overrides=None):
        d = HYPERPARAMETERS.copy()
        if overrides:
            d.update(overrides)
        for k, v in d.items():
            setattr(self, k, v)

    def __repr__(self):
        return f"Config({', '.join(f'{k}={v!r}' for k,v in HYPERPARAMETERS.items())})"