#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# autolatex/utils/latex_log_parser.py
# Copyright (C) 2013  Stephane Galland <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

#---------------------------------
# IMPORTS
#---------------------------------

# Import standard python libs
import os
import re
# Import AutoLaTeX libraries
import utils

#---------------------------------
# INTERNATIONALIZATION
#---------------------------------

import gettext
_T = gettext.gettext



class TeXWarning:
       def __init__(self, filename, extension, line, message):
               self._data = {}
               if extension:
                       self._filename = filename.strip()+extension
               else:
                       self._filename = filename.strip()
               self._linenumber = line
               expr = re.compile("[\n\r\f\t ]+")
               self._message = re.sub(expr, ' ', message)

       def append(self, message):
               self._message = self._message + message

       def set_data(self, key, value):
               self._data[key] = value

       def get_data(self, key):
               return self._data[key]

       def get_all_data(self):
               return self._data

       def get_filename(self):
               return self._filename

       def get_line_number(self):
               return self._linenumber

       def get_message(self):
               return self._message

       def set_message(self, message):
               self._message = message

       def __str__(self):
               s = str(self._filename)+":"+str(self._linenumber)+":"+str(self._message)+"\n"
               if self._data:
                       s = s + self._data
               return s

class Parser:

       def __init__(self, log_file):
               self._directory = os.path.dirname(log_file)
               #
               self._warnings = []
               # Parsing the log file
               regex_start = re.compile("^\\!\\!\\!\\!\\[BeginWarning\\](.*)$")
               regex_end = re.compile("^\\!\\!\\!\\!\\[EndWarning\\]")
               regex_warn = re.compile("^(.*?):([^:]*):([0-9]+):\\s*(.*?)\\s*$")
               f = open(log_file, 'r')
               current_log_block = ''
               warning = False
               line = f.readline()
               while line:
                       if warning:
                               mo = re.match(regex_end, line)
                               if mo:
                                       mo = re.match(regex_warn, current_log_block)
                                       if mo:
                                               w = TeXWarning(
                                                       mo.group(1),
                                                       mo.group(2),
                                                       mo.group(3),
                                                       mo.group(4))
                                               self._warnings.append(w)
                                       warning = False
                                       current_log_block = ''
                               else:
                                       l = line
                                       if not l.endswith(".\n"):
                                               l = l.rstrip()
                                       current_log_block = current_log_block + l
                       else:
                               mo = re.match(regex_start, line)
                               if mo:
                                       l = mo.group(1)
                                       if not l.endswith(".\n"):
                                               l = l.rstrip()
                                       current_log_block = l
                                       warning = True
                       line = f.readline()

               if warning and current_log_block:
                       mo = re.match(regex_warn, current_log_block)
                       if mo:
                               w = TeXWarning(
                                       mo.group(1),
                                       mo.group(2),
                                       mo.group(3),
                                       mo.group(4))
                               self._warnings.append(w)

       def __str__(self):
               text = ""
               for w in self._warnings:
                       text = text + str(w) + "\n"
               return text

       def get_undefined_citation_warnings(self):
               regex = re.compile(
                               "^.*citation\\s*\\`([^']+)\\'.+undefined.*$",
                               re.I|re.S)
               warnings = []
               for warning in self._warnings:
                       message = warning.get_message()
                       mo = re.match(regex, message)
                       if mo:
                               warning.set_message(
                                       warning.get_filename()+":"+
                                       str(warning.get_line_number())+": "+
                                       (_T("Citation '%s' undefined") % mo.group(1)))
                               warnings.append(warning)
               return warnings

       def get_undefined_reference_warnings(self):
               regex = re.compile(
                               "^.*reference\\s*\\`([^']+)\\'.+undefined.*$",
                               re.I|re.S)
               warnings = []
               for warning in self._warnings:
                       message = warning.get_message()
                       mo = re.match(regex, message)
                       if mo:
                               warning.set_message(
                                       warning.get_filename()+":"+
                                       str(warning.get_line_number())+": "+
                                       (_T("Reference '%s' undefined") % mo.group(1)))
                               warnings.append(warning)
               return warnings

       def get_multidefined_label_warnings(self):
               regex = re.compile(
                               "^.*label\\s*\\`([^']+)\\'.+multiply\\s+defined.*$",
                               re.I|re.S)
               warnings = []
               for warning in self._warnings:
                       message = warning.get_message()
                       mo = re.match(regex, message)
                       if mo:
                               warning.set_message(
                                       warning.get_filename()+":"+
                                       str(warning.get_line_number())+": "+
                                       (_T("Label '%s' multiply defined") % mo.group(1)))
                               warnings.append(warning)
               return warnings