#!/usr/bin/env fuchsia-vendored-python
# Copyright 2026 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Checks Fuchsia Git commit messages for style guidelines.

Based on //docs/contribute/commit-message-style-guide.md:
- First line summary length (recommended <= 50, warning > 65).
- Body lines wrapped at 72 characters (excluding URLs, footers, and code blocks).
"""

import argparse
import json
import re
import subprocess
import sys
from typing import List, Literal, Optional, TypedDict

SUBJECT_REC_MAX_LEN = 50
SUBJECT_WARN_MAX_LEN = 65
BODY_MAX_LEN = 72

URL_REGEX = re.compile(r"https?://[^\s]+")
# Footers that are exempt from line length checks
FOOTER_REGEX = re.compile(
    r"^(Bug|Fixed|Test|Change-Id|Cq-Include-Trybots|Fuchsia-Auto-Submit|Multiply|Depends-on|Run-All-Tests|Exempt|No-Tree-Checks|No-Presubmit|No-Try|TAG|CONV)[:=]"
)
# Reverts and relands take the original subject and prepend "Revert " or "Reland ".
# These are exempt from the length check to avoid manual rewrites of auto-generated subjects.
REVERT_RELAND_REGEX = re.compile(r"^(?:Revert(?:\^\d+)?|Reland) ")


class Finding(TypedDict, total=False):
    level: Literal["warning", "error"]
    message: str
    filepath: str
    line: int


class CommitInfo(TypedDict):
    hash: str
    message: str


def check_commit_message(
    message: str, filepath: str = ".git/COMMIT_MSG"
) -> List[Finding]:
    findings: List[Finding] = []
    lines = message.splitlines()
    if not lines:
        return findings

    subject = lines[0]

    # Check subject line length
    if len(subject) > SUBJECT_WARN_MAX_LEN and not REVERT_RELAND_REGEX.match(
        subject
    ):
        findings.append(
            {
                "level": "warning",
                "message": f"Subject line exceeds {SUBJECT_WARN_MAX_LEN} characters ({len(subject)} chars). Limit first line to {SUBJECT_REC_MAX_LEN}-{SUBJECT_WARN_MAX_LEN} characters.",
                "filepath": filepath,
                "line": 1,
            }
        )

    # Check body line length (wrap at 72 chars) starting from line 3 (if body exists)
    for i, line in enumerate(lines[2:], start=3):
        if len(line) <= BODY_MAX_LEN:
            continue
        # Allow lines containing URLs
        if URL_REGEX.search(line):
            continue
        # Allow standard footers (e.g. Change-Id, Bug, etc.)
        if FOOTER_REGEX.match(line):
            continue
        # Allow indented code block / stack trace lines or quoted revert lines
        if line.startswith(("    ", "\t", ">")):
            continue
        findings.append(
            {
                "level": "warning",
                "message": f"Line {i} exceeds {BODY_MAX_LEN} characters ({len(line)} chars). Wrap body text at {BODY_MAX_LEN} characters.",
                "filepath": filepath,
                "line": i,
            }
        )

    return findings


def get_git_commit_messages(
    rev: str, cwd: Optional[str] = None
) -> List[CommitInfo]:
    """Returns a list of commit messages for the specified git revision range."""
    cmd = ["git", "log", "--format=%H%x00%B%x00", rev]
    try:
        proc = subprocess.run(
            cmd,
            cwd=cwd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            check=True,
        )
    except subprocess.CalledProcessError as e:
        sys.stderr.write(f"Failed to read git commit message: {e.stderr}\n")
        return []

    output = proc.stdout
    commits: List[CommitInfo] = []
    parts = output.split("\x00")
    for i in range(0, len(parts) - 1, 2):
        commits.append(CommitInfo(hash=parts[i].strip(), message=parts[i + 1]))
    return commits


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--message", help="Commit message string to check literally."
    )
    parser.add_argument(
        "--message-file", help="Path to file containing commit message."
    )
    parser.add_argument(
        "--rev",
        default="-1",
        help="Git revision or range to check (default: -1 for latest commit).",
    )
    parser.add_argument(
        "--json",
        action="store_true",
        help="Output findings formatted as JSON array for Shac.",
    )
    parser.add_argument(
        "--strict",
        action="store_true",
        help="Return non-zero exit code if any warnings or errors are found.",
    )
    args = parser.parse_args()

    findings: List[Finding] = []

    if args.message is not None:
        findings.extend(check_commit_message(args.message))
    elif args.message_file is not None:
        with open(
            args.message_file, "r", encoding="utf-8", errors="replace"
        ) as f:
            findings.extend(
                check_commit_message(f.read(), filepath=args.message_file)
            )
    else:
        commits = get_git_commit_messages(args.rev)
        for commit in commits:
            findings.extend(check_commit_message(commit["message"]))

    if args.json:
        print(json.dumps(findings, indent=2))
    else:
        for finding in findings:
            level = finding["level"].upper()
            msg = finding["message"]
            line_info = (
                f" (line {finding['line']})" if "line" in finding else ""
            )
            print(f"[{level}]{line_info}: {msg}")

    has_errors = any(f["level"] == "error" for f in findings)
    has_warnings = any(f["level"] == "warning" for f in findings)

    if has_errors or (args.strict and has_warnings):
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
