"""Random Search — the plain keep-all loop with uniform-random selection instead of greedy elitism.

A deliberately small community baseline. One module per component (mirroring the Galapagos scaffold
layout), and every module is self-contained in this package — Random search does not borrow another
scaffold's classes:

  population.py        -> RandomPopulation       (uncapped keep-all leaderboard)
  selection_policy.py  -> RandomSelectionPolicy  (uniform-random parent + inspirations)
  prompt_builder.py    -> RandomPromptBuilder    (the default multi-section template)
  proposer.py          -> RandomProposer         (SEARCH/REPLACE diff)
  evaluator.py         -> RandomEvaluator        (task-supplied)
  memory.py            -> RandomMemory           (none)
  scaffold.py          -> RandomScaffold         (the orchestrator that composes the six)

The only behavioral change from a greedy Top-K baseline is *selection*: every iteration samples a
parent uniformly from the full candidate history and draws distinct random inspirations. Everything
else — keep-all population, default prompt, SEARCH/REPLACE diff, null memory — is held identical, so
that random vs. elitist selection is the single independent variable. That is what makes this a clean
exploration-oriented comparison point for adaptive search.
"""
from __future__ import annotations

from ...config import GalapagosConfig
from ...models import GalapagosModel
from ..base_scaffold import GalapagosScaffold
from ..registry import register_scaffold
# one module per component — all self-contained in this package
from .memory import RandomMemory
from .population import RandomPopulation
from .prompt_builder import RandomPromptBuilder
from .proposer import RandomProposer
from .selection_policy import RandomSelectionPolicy


@register_scaffold("random")
class RandomScaffold(GalapagosScaffold):
    """The plain loop with uniform-random selection instead of elitism."""

    name = "random"

    @classmethod
    def build_components(cls, config: GalapagosConfig, model: GalapagosModel | None) -> dict:
        return {
            "population": RandomPopulation(capacity=config.population.capacity),
            "selection_policy": RandomSelectionPolicy(
                seed=int(config.seed),
                num_inspirations=int(config.selection_policy.num_inspirations),
            ),
            "prompt_builder": RandomPromptBuilder(),
            "proposer": RandomProposer(),
            "memory": RandomMemory(),
        }
