"""Random-search SelectionPolicy component — uniform-random parent and context.

This is the one component that differs from a greedy keep-all baseline. Instead of taking the rank-1
program as the parent and ranks 2..K+1 as context, every iteration draws the parent uniformly from the
full population and samples distinct inspirations uniformly from the rest. Fitness plays no role — that
is the point of the baseline.
"""
from __future__ import annotations

from ...components.selection import SelectionPolicy
from ...records import LoopContext, Selection


class RandomSelectionPolicy(SelectionPolicy):
    """Select a uniform-random parent and distinct random inspirations over the whole history.

    The draws use the base policy's seeded :attr:`rng`, so a given ``seed`` and population history
    reproduce the same choices, and the inherited ``state_dict`` checkpoints the RNG cursor so a resumed
    run continues the same stream. On the lone-seed step (no other candidates yet) the seed is used as
    its own inspiration, so the inspiration set is never empty.
    """

    def __init__(self, seed: int = 0, num_inspirations: int = 4):
        super().__init__(seed)
        self.num_inspirations = max(0, int(num_inspirations))

    def select(self, population, ctx: LoopContext | None = None) -> Selection:
        members = population.all()
        if not members:
            raise RuntimeError("cannot select from an empty population")

        parent = self.rng.choice(members)
        candidates = [genome for genome in members if genome.id != parent.id]
        count = min(self.num_inspirations, len(candidates))
        inspirations = self.rng.sample(candidates, count)
        if not inspirations:
            inspirations = [parent]
        return Selection(
            parent=parent,
            inspirations=inspirations,
            pool=members,
            details={
                "selection_strategy": "uniform_random",
                "selection_mode": "explore",
                "requested_inspirations": self.num_inspirations,
            },
        )
