#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 1998-2026 Stephane Galland <galland@arakhne.org>
#
# This program is free library; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; see the file COPYING.  If not,
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite
# 330, Boston, MA 02111-1307, USA.

"""
BibTeX tools.
"""

import re
from typing import Any, override
from autolatex2.tex.abstractbibliography import BibliographyErrorParser

class BibTeXErrorParser(BibliographyErrorParser):
	"""
	Parser for errors generated by BibTeX.
	"""

	def __init__(self):
		"""
		Construct the parser.
		"""
		pass

	# noinspection PyIncorrectDocstring
	@override
	def parse_log(self, default_filename : str, log : str) -> dict[str,Any] | None:
		current_error = dict()
		previous_line = ''
		for line in re.split(r'[\n\r]',  log):
			if current_error:
				m = re.search(r'^\s*:\s*(.*?)\s*$', line, re.S)
				if m:
					current_error['message'] += " " + m.group(1)
				else:
					return current_error
			else:
				m = re.search(r'^\s*(.*?)\s*---line\s+([0-9]+)\s+of\s+file\s+(.*?)\s*$', line, re.IGNORECASE | re.S)
				if m:
					message = m.group(1)
					lineno = int(m.group(2))
					filename = m.group(3)
					if not message:
						message = previous_line.strip()
					current_error = {
						'filename': filename, 
						'lineno': lineno, 
						'message': message
					}
					previous_line = ''
				else:
					previous_line = line
					current_error = dict()
		if current_error:
			return current_error
		return None

