# Copyright (C) 2008 LottaNZB Development Team
# 
# 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; version 3.
# 
# 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; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""Contains classes for all messages put out by the PostProcessor module."""

from gettext import ngettext

from lottanzb.hellalog import LogRecord, _Plural, _FatalErrorHandler, _ExceptionHandler
from lottanzb.util import _

class RunError(_FatalErrorHandler, LogRecord): # PostProcessor.run()
    PATTERN = r"(?P<archive_name>.+): A problem occurred"
    TEMPLATE = _("A problem occured while post-processing %(archive_name)s")

class DirectoryCreationFatal(LogRecord): # PostProcessor.moveDestDir()
    PATTERN = r"Unable to create directory for category: (?P<directory>.+) error: (?P<error_message_detailed>.+)"
    TEMPLATE = _("Unable to create directory %(directory)s: %(error_message_detailed)s")

class DecompressingMusicFatal(LogRecord): # PostProcessor.processMusic()
    PATTERN = r"Failed to complete music decompression"
    TEMPLATE = _("Failed to complete music decompression")

class InexistentDirectoryFatal(LogRecord): # PostProcessor.postProcess()
    PATTERN = r"Directory does not exist: (?P<directory>.+)"
    TEMPLATE = _("The directory %(directory)s does not exist")

class NotADirectoryFatal(LogRecord): # PostProcessor.postProcess()
    PATTERN = r"Not a directory: (?P<directory>.+)"
    TEMPLATE = _("%(directory)s is not a directory")

class NotAProcessedDirectoryFatal(NotADirectoryFatal): # PostProcessor.postProcess()
    PATTERN = r"Unable to create processed dir, a non dir already exists there: (?P<directory>.+)"
    TEMPLATE = _("%(directory)s is not a directory")

class BrokenFilesFatal(LogRecord): # PostProcessor.
    PATTERN = r"Unable to process directory: (?P<directory>.+)\nThis directory has the following broken files: \n(?P<files>.+)and contains no par2 files for repair\z"
    TEMPLATE = _("Unable to process directory %(directory)s. It contains broken files and no PAR files for repair.")

class ProcessDirCreationWarning(LogRecord): # PostProcessor.postProcess()
    PATTERN = r"^Unable to create processedDir: (?P<directory>.+) err: (?P<error_message>.+)$"
    TEMPLATE = _("Unable to create directory %(directory)s: %(error_message)s")

class UnhandledRunError(_ExceptionHandler, LogRecord): # PostProcessor.run()
    PATTERN = r"(?P<archive_name>.+): A unexpected problem occurred"
    TEMPLATE = _("A unexpected problem occured while post-processing %(archive_name)s")

class SkippingMusicDecompressionInfo(LogRecord): # PostProcessor.processMusic()
    PATTERN = r"^(?P<archive_name>.+): Skipping music file decompression$"
    TEMPLATE = _("%(archive_name)s: Skipping music file decompression")

class DecompressingMusicInfo(LogRecord): # PostProcessor.processMusic()
    PATTERN = r"^(?P<archive_name>.+): Decompressing (?P<file_count>\d+) files? \(formats?: (?P<music_types>.+)\) via (?P<thread_count>\d+) threads?..$"
    TEMPLATE = _("%(archive_name)s: Decompressing %(file_message)s (%(music_types)s) via %(thread_message)s...")
    
    def set_data(self, data):
        file_count = int(data["file_count"])
        thread_count = int(data["thread_count"])
        
        data["thread_message"] = ngettext(_("%i thread"), _("%i threads"), thread_count) % thread_count
        data["file_message"] = ngettext(_("%i file"), _("%i files"), file_count) % file_count
        
        LogRecord.set_data(self, data)

class DecompressingMusigFinishedInfo(_Plural, LogRecord): # PostProcessor.processMusic()
    PATTERN = r"^(?P<archive_name>.+): Finished decompressing \((?P<file_count>\d+) files?, took: (?P<elapsed_time>.+)\)$"
    TEMPLATE = _("%(archive_name)s: Finished decompressing of %(file_count)s file in %(elapsed_time)s")
    TEMPLATE_2 = _("%(archive_name)s: Finished decompressing of %(file_count)s files in %(elapsed_time)s")

class ProcessingFinishedInfo(LogRecord): # PostProcessor.finishedPostProcess()
    PATTERN = r"^(?P<archive_name>.+): Finished processing \(took: (?P<elapsed_time>.+)( \(total: (?P<total_elapsed_time>.+)\))?( \((?P<no_pars>No Pars)\))?\)$"
    TEMPLATE = _("%(archive_name)s: Finished processing (took: %(elapsed_time)s)%(total_message)s%(no_pars_message)s")
    
    def set_data(self, data):
        data.update({
            "no_pars" : data["no_pars"] == "No Pars",
            "no_pars_message" : "",
            "total_message" : ""
        })
        
        if data["no_pars"]:
            data["no_pars_message"] = _(" (no PARs)")
        
        if data["total_elapsed_time"]:
            data["total_message"] = _(" (total: %s)") % data["total_elapsed_time"]
        
        LogRecord.set_data(self, data)

class ParExpectsUnsplitFilesInfo(LogRecord): # PostProcessor.postProcess()
    PATTERN = r"^(?P<archive_name>.+): This archive requires assembly before running par2$"
    TEMPLATE = _("%(archive_name)s: This archive requires assembly before running par2")

class ForcingParDownloadInfo(LogRecord): # PostProcessor.triggerParRecovery(...)
    PATTERN = r"^(?P<archive_name>.+): More pars available, forcing extra par download$"
    TEMPLATE = _("%(archive_name)s: More PARs available, forcing extra PAR download")

class MoreRecoveryNeededInfo(LogRecord): # PostProcessor.triggerParRecovery(...)
    PATTERN = r"^(?P<archive_name>.+): Failed par verify, requires (?P<needed_blocks>/d+) more recovery (?P<recovery_name>.*)$"
    TEMPLATE = _("%(archive_name)s: Failed PAR verify, requires %(needed_blocks)s more recovery %(recovery_name)s")
