"""Normal whole-line mutation and auxiliary full-rewrite merge proposers."""
from __future__ import annotations

from ...components.proposer import FullRewrite, LLMProposer, WholeLineDiff


class GepaNativeProposer(LLMProposer):
    """SkyDiscover normal proposal: strict whole-line diff, or configured full rewrite."""

    edit_strategy = WholeLineDiff()

    def _decorate_child(self, child, env):
        # Genome.child() intentionally inherits generic policy metadata.  Merge provenance, however,
        # describes the parent operation rather than a heritable trait; leaving it in place would make
        # a later ordinary mutation take the merge acceptance path.
        for key in (
            "gepa_native_merge",
            "gepa_native_admitted",
            "admitted",
            "merge_score_a",
            "merge_score_b",
            "other_context_ids",
            "parent_info",
            "context_info",
        ):
            child.metadata.pop(key, None)
        parent = env.selection.parent
        context_ids = [
            genome.id
            for genome in env.selection.inspirations
            if parent is None or genome.id != parent.id
        ]
        child.metadata.update({
            "iteration": env.ctx.iteration if env.ctx is not None else None,
            "other_context_ids": context_ids,
            "parent_info": ["", parent.id] if parent is not None else None,
            "context_info": [["", program_id] for program_id in context_ids],
        })
        # SkyDiscover rejects an identical result as a parse failure only in diff mode.  A non-empty
        # full rewrite is evaluated even if it is byte-identical, then rejected by the stored-parent
        # equality gate.  The shared Galapagos proposer normally marks either form as a no-op.
        if self.mutation_approach.name == "full_rewrite" and child.content:
            child.metadata["changed"] = True
        return child


class GepaNativeMergeProposer(LLMProposer):
    """One always-full-rewrite crossover call used outside the normal iteration budget."""

    edit_strategy = FullRewrite()
    evolution_operator = "crossover"
