import re
from sys import stderr

import pygit2

from distgit.hooks import CommitMsg, Hook, HookResult

"""
Commit-Msg Pattern Hook (Client-side)
Validates the commit message against a regular expression.
"""


class CommitMsgPattern(CommitMsg):
	def __init__(self, repo: pygit2.Repository, pattern: str):
		super().__init__(repo)
		self.exp = re.compile(pattern)

	def run(self, message_file: str) -> HookResult:
		with open(message_file) as f:
			message = f.read()
		if not self.exp.match(message):
			stderr.write(f"Commit message does not match pattern: {self.exp.pattern}\n")
			return HookResult.FAILURE
		return HookResult.SUCCESS


"""
Update Pattern Hook (Server-side)
Invoked by git-receive-pack once per ref being updated, before the ref is updated.
Use this hook to:
- Enforce fast-forward only (reject non-FF updates)
- Implement per-ref access control
- Log or validate old → new for specific refs
Takes three parameters: ref name, old object name, new object name.
"""


class UpdatePattern(Hook):
	def __init__(self, repo: pygit2.Repository, ref_pattern: str, msg_pattern: str):
		super().__init__(repo)
		self.ref_exp = re.compile(ref_pattern)
		self.msg_exp = re.compile(msg_pattern)

	def run(self, ref_name: str, old_oid: str, new_oid: str) -> HookResult:
		if self.ref_exp.match(ref_name):
			commit = self.repo.revparse_single(new_oid).peel(pygit2.Commit)
			if not self.msg_exp.match(commit.message):
				stderr.write(f"Commit message does not match pattern: {self.msg_exp.pattern}\n")
				return HookResult.FAILURE
		return HookResult.SUCCESS