#!/usr/bin/env python3
"""Validate Conventional Commit messages for Orquestra.

Allowed format:
  <type>[optional scope][!]: <description>

Examples:
  feat(orders): add awaiting-payment notifications
  fix(DEPLOY-MONOLITH-CLEANUP): clean stale deployments
  chore(release)!: v1.0.0
"""
from __future__ import annotations

import argparse
import re
import sys
from pathlib import Path

ALLOWED_TYPES = {
    'build',
    'chore',
    'ci',
    'docs',
    'feat',
    'fix',
    'perf',
    'refactor',
    'revert',
    'style',
    'test',
}

HEADER_RE = re.compile(
    r'^(?P<type>build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)'
    r'(?:\((?P<scope>[A-Za-z0-9._/-]+)\))?'
    r'(?P<breaking>!)?: (?P<description>\S.{0,119})$'
)


def validate(message: str) -> tuple[bool, str | None]:
    lines = message.strip('\n').splitlines()
    if not lines or not lines[0].strip():
        return False, 'empty commit message'

    header = lines[0].strip()
    match = HEADER_RE.match(header)
    if not match:
        return (
            False,
            "first line must be Conventional Commit: "
            "<type>[optional scope][!]: <description>",
        )

    commit_type = match.group('type')
    if commit_type not in ALLOWED_TYPES:
        return False, f"unsupported type '{commit_type}'"

    description = match.group('description').strip()
    if description.endswith('.'):
        return False, 'description must not end with a period'

    if any(line.rstrip() != line for line in lines):
        return False, 'commit message contains trailing whitespace'

    if len(lines) > 1 and lines[1].strip():
        return False, 'second line must be blank before body/footer'

    return True, None


def main() -> int:
    parser = argparse.ArgumentParser(description='Validate Conventional Commit message')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--file', type=Path, help='commit message file')
    group.add_argument('--message', help='commit message string')
    args = parser.parse_args()

    message = args.message if args.message is not None else args.file.read_text(encoding='utf-8')
    ok, error = validate(message)
    if ok:
        return 0

    print(f'[FAIL] Invalid commit message: {error}', file=sys.stderr)
    print('', file=sys.stderr)
    print('Examples:', file=sys.stderr)
    print('  feat(orders): add awaiting-payment notifications', file=sys.stderr)
    print('  fix(monolith): clean stale deployments before start', file=sys.stderr)
    print('  chore(release): v0.2.0', file=sys.stderr)
    return 1


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