#!/usr/bin/env python3
"""Fail-closed Forgejo pre-receive gate for Lake Lamp repo-push grants."""
import json
import os
import re
import sys
import time

GRANT_DIR = os.environ.get("REPO_AUTHORIZATION_DIR", "/var/lib/guanghu/repo-authorizations")


def normalize_repo(value):
    value = value.strip().lower().removesuffix(".git")
    match = re.search(r"(?:gitea-repositories|repositories)/([^/]+/[^/]+)$", value)
    if match:
        return match.group(1)
    # Forgejo's hook environment may expose only the repository name.
    # This instance is single-owner and the allowlist below remains authoritative.
    if re.fullmatch(r"[a-z0-9._-]+", value):
        return f"bingshuo/{value}"
    return value


def check(repo, now=None):
    now = time.time() if now is None else now
    repo = normalize_repo(repo)
    if not re.fullmatch(r"bingshuo/[a-z0-9._-]+", repo):
        return False, "repository_not_allowlisted"
    filename = os.path.join(GRANT_DIR, repo.replace("/", "__") + ".json")
    try:
        with open(filename, encoding="utf-8") as handle:
            grant = json.load(handle)
    except (OSError, ValueError):
        return False, "repo_push_approval_required"
    if grant.get("repo") != repo or grant.get("target") != "JD-FD-PRIMARY":
        return False, "repo_push_grant_binding_mismatch"
    if now > float(grant.get("expires_at", 0)):
        return False, "repo_push_grant_expired"
    return True, "ok"


if __name__ == "__main__":
    repo = os.environ.get("FORGEJO_REPO") or os.environ.get("GIT_DIR") or os.getcwd()
    ok, reason = check(repo)
    if not ok:
        print(f"小湖灯推送门已锁定: {reason}。请提交 repo-push 邮件工单。", file=sys.stderr)
        sys.exit(1)
