#!/usr/bin/env python3
"""校验 commit message 符合 Conventional Commits 规范

规则：
  <type>(<scope>): <description>

- type:  必填，限指定列表
- scope: 可选，括号内字母数字和 -
- 冒号后必须有一个空格
- description 不能为空
- 支持 ! 标记破坏性变更，如 feat!:

环境变量 CONVENTIONAL_TYPES 可覆盖允许的 type 列表（逗号分隔）。
"""

import os
import re
import sys

# 允许的 type 列表
DEFAULT_TYPES = [
    "feat", "fix", "docs", "style", "refactor",
    "perf", "test", "chore", "ci", "revert", "build",
]

ALLOWED_TYPES = os.environ.get(
    "CONVENTIONAL_TYPES",
    ",".join(DEFAULT_TYPES),
).split(",")

# 正则：<type>[(<scope>)][!]: <description>
# feat(log): add syslog    → 通过
# feat!: breaking change   → 通过
# feat(log)!: breaking     → 通过
# fix: typo                → 通过
# Merge branch ...         → 跳过
# wip                      → 拒绝
PATTERN = re.compile(
    r"^(?P<type>" + "|".join(re.escape(t) for t in ALLOWED_TYPES) + r")"
    r"(\((?P<scope>[a-zA-Z0-9_.-]+)\))?"
    r"(?P<breaking>!)?"
    r": (?P<description>.+)$"
)

MERGE_PATTERNS = [
    re.compile(r"^Merge (branch|pull request|remote-tracking)"),
    re.compile(r"^Revert "),
    re.compile(r"^Squashed commit"),
]


def main():
    commit_msg_file = sys.argv[1]

    with open(commit_msg_file, "r", encoding="utf-8") as f:
        lines = f.readlines()

    if not lines:
        print("❌ Commit message 为空")
        return 1

    subject = lines[0].strip()

    # 跳过自动生成的 merge / revert 消息
    for pat in MERGE_PATTERNS:
        if pat.match(subject):
            return 0

    match = PATTERN.match(subject)
    if not match:
        print(f"❌ Commit message 格式错误: {subject}")
        print()
        print("   期望格式: <type>(<scope>): <description>")
        print()
        print(f"   允许的 type: {', '.join(ALLOWED_TYPES)}")
        print("   示例:")
        print("     feat(log): 新增 LOG_TO_SYSLOG")
        print("     fix: 修复日志刷新死锁")
        print("     refactor(odf)!: 重构校验框架")
        return 1

    # 检查 body（第二行应为空行）
    if len(lines) > 1 and lines[1].strip() != "":
        print("⚠️  Warning: subject 与 body 之间应有空行")

    print(f"✅ commit message 格式正确: {subject}")
    return 0


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