"""Convert the published Erdős 671 Lean proof from cubic to square samples.

Usage:
    python apply_Erdos671_square_samples.py Erdos671.lean Erdos671_square.lean

The input is the 2,830-line Lean source linked from the proof-claim comments:
https://www.erdosproblems.com/forum/proof-claims/61/comments

The script deliberately checks every expected replacement count. It refuses to
write an output if the source differs from the audited version.
"""

from __future__ import annotations

import sys
from pathlib import Path


OLD_HFIRST = """  have hfirst : Tendsto (fun k : ℕ ↦ 2 * ‖f‖ * (1 / (k + 1 : ℝ)) ^ 2)
      atTop (𝓝 0) := by
    simpa using (tendsto_const_nhds.mul (hinv.pow 2) :
      Tendsto (fun k : ℕ ↦ (2 * ‖f‖) * (1 / (k + 1 : ℝ)) ^ 2) atTop
        (𝓝 ((2 * ‖f‖) * 0 ^ 2)))"""

NEW_HFIRST = """  have hfirst : Tendsto (fun k : ℕ ↦ 2 * ‖f‖ * (1 / (k + 1 : ℝ)))
      atTop (𝓝 0) := by
    simpa using (tendsto_const_nhds.mul hinv :
      Tendsto (fun k : ℕ ↦ (2 * ‖f‖) * (1 / (k + 1 : ℝ))) atTop
        (𝓝 ((2 * ‖f‖) * 0)))"""

OLD_NORM = "      norm_num [fillerEmbedding, fillerZoneEmbedding] at h'"
NEW_NORM_1 = (
    "      change (z i : ℝ) = "
    "((fillerSource d j' : FillerZone) : ℝ) at h'"
)
NEW_NORM_2 = (
    "      change ((fillerSource d j : FillerZone) : ℝ) = "
    "(z i' : ℝ) at h'"
)


def transform(source: str) -> str:
    if source.count("^ 3") != 40:
        raise ValueError(
            f"expected 40 cubic-power occurrences, found {source.count('^ 3')}"
        )
    target = "2 * ‖f‖ * (1 / (k + 1 : ℝ)) ^ 2 +"
    if source.count(target) != 2:
        raise ValueError(
            f"expected 2 selected-error targets, found {source.count(target)}"
        )
    if source.count(OLD_HFIRST) != 1:
        raise ValueError("expected exactly one cubic first-term limit block")
    if source.count(OLD_NORM) != 2:
        raise ValueError(
            "expected exactly two mathlib compatibility sites "
            f"(found {source.count(OLD_NORM)})"
        )
    if source.count("pow_pos hk 3") != 1:
        raise ValueError("expected exactly one base pigeonhole positivity proof")
    if source.count("pow_pos (Nat.zero_lt_succ k) 3") != 1:
        raise ValueError("expected exactly one stage-edge positivity proof")

    result = source.replace("^ 3", "^ 2")
    result = result.replace("pow_pos hk 3", "pow_pos hk 2")
    result = result.replace(
        "pow_pos (Nat.zero_lt_succ k) 3",
        "pow_pos (Nat.zero_lt_succ k) 2",
    )
    result = result.replace(
        target,
        "2 * ‖f‖ * (1 / (k + 1 : ℝ)) +",
    )
    result = result.replace(OLD_HFIRST, NEW_HFIRST)
    result = result.replace(OLD_NORM, NEW_NORM_1, 1)
    result = result.replace(OLD_NORM, NEW_NORM_2, 1)

    if "^ 3" in result or OLD_NORM in result or OLD_HFIRST in result:
        raise AssertionError("postcondition failed: an old fragment remains")
    return result


def main() -> int:
    if len(sys.argv) != 3:
        print(
            "usage: python apply_Erdos671_square_samples.py "
            "INPUT.lean OUTPUT.lean"
        )
        return 2
    source_path = Path(sys.argv[1])
    output_path = Path(sys.argv[2])
    source = source_path.read_text(encoding="utf-8")
    result = transform(source)
    output_path.write_text(result, encoding="utf-8", newline="\n")
    print(
        f"wrote {output_path} "
        f"({len(result)} characters, {result.count(chr(10)) + 1} lines)"
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
