"""NexaOffice release policy checker.

Rules kept here:
- Version format: vYYYY.MM.DD.NN/NNN
- Daily reset is handled by tools/bump_release_version.py
- Every 10 versions, a larger self-check / optimization pass must be recorded.

Usage:
    python tools/release_policy_check.py
    python tools/release_policy_check.py --write-report
"""
from __future__ import annotations

import argparse
import json
import re
from datetime import datetime
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
CONSTANTS = ROOT / "core" / "constants.py"
REPORT_PATH = ROOT / "data" / "release_policy_latest.json"
MILESTONE_INTERVAL = 10
VERSION_RE = re.compile(r'APP_VERSION\s*=\s*"v(\d{4})\.(\d{2})\.(\d{2})\.(\d{2,3})"')


def read_current_version() -> str:
    text = CONSTANTS.read_text(encoding="utf-8")
    match = VERSION_RE.search(text)
    if not match:
        raise RuntimeError("APP_VERSION missing or invalid; expected vYYYY.MM.DD.NN or vYYYY.MM.DD.NNN/NNN")
    return "v" + ".".join(match.groups())


def parse_version(version: str) -> dict:
    match = re.fullmatch(r"v(\d{4})\.(\d{2})\.(\d{2})\.(\d{2,3})", version)
    if not match:
        raise RuntimeError(f"Invalid version: {version}")
    year, month, day, seq = match.groups()
    return {
        "version": version,
        "date_code": f"{year}{month}{day}",
        "date_text": f"{year}-{month}-{day}",
        "prefix": f"v{year}.{month}.{day}",
        "sequence": int(seq),
        "sequence_text": seq,
    }


def milestone_doc_name(info: dict) -> str:
    return f"TEN_VERSION_MILESTONE_{info['date_code']}_{info['sequence']:02d}_CN.md"


def build_report(version: str | None = None) -> dict:
    info = parse_version(version or read_current_version())
    sequence = info["sequence"]
    due_now = sequence > 0 and sequence % MILESTONE_INTERVAL == 0
    last_milestone_seq = (sequence // MILESTONE_INTERVAL) * MILESTONE_INTERVAL
    if last_milestone_seq == 0:
        last_milestone = ""
    else:
        last_milestone = f"{info['prefix']}.{last_milestone_seq:02d}"
    next_milestone_seq = sequence + (MILESTONE_INTERVAL - sequence % MILESTONE_INTERVAL)
    if due_now:
        next_milestone_seq = sequence + MILESTONE_INTERVAL
    next_milestone = f"{info['prefix']}.{next_milestone_seq:02d}"
    doc_path = ROOT / "docs" / milestone_doc_name(info)
    return {
        "checked_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "current_version": info["version"],
        "release_date": info["date_text"],
        "release_sequence_today": sequence,
        "milestone_interval": MILESTONE_INTERVAL,
        "ten_version_check_due_now": due_now,
        "milestone_doc_expected": str(doc_path.relative_to(ROOT)),
        "milestone_doc_exists": doc_path.exists(),
        "last_milestone_version": last_milestone,
        "next_milestone_version": next_milestone,
        "status": "OK" if (not due_now or doc_path.exists()) else "MILESTONE_DOC_MISSING",
        "rules": [
            "Version format is vYYYY.MM.DD.NN/NNN.",
            "If the release date changes, NN resets to 01.",
            "Every 10 versions, run and record a larger self-check / optimization pass.",
        ],
    }


def write_report(report: dict) -> None:
    REPORT_PATH.parent.mkdir(parents=True, exist_ok=True)
    REPORT_PATH.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--write-report", action="store_true", help="write data/release_policy_latest.json")
    args = parser.parse_args()
    report = build_report()
    if args.write_report:
        write_report(report)

    print("NexaOffice Release Policy Check")
    print(f"- Current version: {report['current_version']}")
    print(f"- Sequence today: {report['release_sequence_today']}")
    print(f"- Ten-version major check due now: {'YES' if report['ten_version_check_due_now'] else 'NO'}")
    print(f"- Last milestone: {report['last_milestone_version'] or 'none yet'}")
    print(f"- Next milestone: {report['next_milestone_version']}")
    if report["ten_version_check_due_now"]:
        print(f"- Milestone doc: {report['milestone_doc_expected']} ({'OK' if report['milestone_doc_exists'] else 'MISSING'})")
    if args.write_report:
        print(f"- Report: {REPORT_PATH.relative_to(ROOT)}")
    return 0 if report["status"] == "OK" else 1


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