# -*- coding: utf-8 -*-

"""
/***************************************************************************
 GraphabAlgoProcessing
                                 A QGIS plugin
 Execute command send by its Children
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2020-07-02
        copyright            : (C) 2020 by ThéMA
        email                : robin.marlinl@gmail.com
        author               : Robin Marlin-Lefebvre
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""

__author__ = 'robin.marlinl@gmail.com'
__date__ = '2020-07-02'
__copyright__ = '(C) 2020 by ThéMA'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import io
import subprocess
from builtins import IOError

from PyQt5.QtCore import QCoreApplication
from qgis.core import (
    QgsProcessingAlgorithm,
    QgsMessageLog,
    Qgis
)

class GraphabException(Exception):
    def __init__(self, message):
        super().__init__(message)

class GraphabAlgoProcessing(QgsProcessingAlgorithm):
    """
    This Processing algorithms should extend the QgsProcessingAlgorithm
    class because it's the main file that execute command.
    """
    def __init__(self, plugin = None):
        super().__init__()
        
        self.executionError = False
        self.plugin = plugin
        self.loglines = []

    def group(self):
        """
        Returns the name of the group this algorithm belongs to. This string
        should be localised.
        """
        return 'Graphab'

    def groupId(self):
        """
        Returns the unique ID of the group this algorithm belongs to. This
        string should be fixed for the algorithm, and must not be localised.
        The group id should be unique within each provider. Group id should
        contain lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        """
        return 'graphab'

    def translate(self, context, string):
        return QCoreApplication.translate(context, string)
        
    def processAlgorithm(self, parameters, context, feedback):
        """
        Execute a given command by adding the java executable at the beginning. Get the output
        of the execution and stock it to show it after the execution. Depending of the command
        this function get important values to make post execution like loading a new Linkset or Graph.
        """

        fused_command = self.provider().getGraphabCommand() + parameters
        QgsMessageLog.logMessage(str(fused_command), 'Processing', Qgis.Info)
        feedback.pushInfo('Graphab command:\n')
        feedback.pushCommandInfo(str(fused_command) + "\n\n")
        feedback.pushInfo('Graphab command output:\n')

        self.loglines = []
        self.loglines.append('Graphab execution console output : ')

        with subprocess.Popen(
                    fused_command,
                    stdout=subprocess.PIPE,
                    stdin=subprocess.DEVNULL,
                    stderr=subprocess.STDOUT
                ) as proc:
            reader = io.TextIOWrapper(proc.stdout, errors='ignore', encoding='utf8')
            p = 0
            line = reader.readline()
            while line != '':
                self.loglines.append(line)
                if line.endswith(": 0,0%\n") or line.endswith(": 0.0%\n"):
                    feedback.pushConsoleInfo(line[0:-7])
                    p = 0
                elif line.endswith("%\n"):
                    p += 0.1
                    feedback.setProgress(p)
                elif "Exception in thread \"main\"" in line:
                    resSplit = line.split("Exception in thread \"main\"")
                    msg = resSplit[-1]
                    exc = GraphabException(msg)
                    feedback.pushDebugInfo("TEST {}".format(str(exc.__class__.__name__)))
                    raise exc
                else:
                    feedback.pushConsoleInfo(line[0:-1])
                if feedback.isCanceled():
                    feedback.pushConsoleInfo("Try to cancel Graphab...")
                    proc.kill()

                line = reader.readline()

            if proc.wait() > 0:
                # raise an exception
                self.executionError = True
                raise IOError("Error during Graphab execution!\n" + ''.join(self.loglines))
            else:
                if feedback.isCanceled():
                    self.executionError = True
                    feedback.pushInfo("GRAPHAB EXECUTION CANCELED\n\n\n")
                else:
                    self.executionError = False
                    feedback.pushInfo("GRAPHAB EXECUTION FINISHED WITH SUCCESS!\n\n\n")


        QgsMessageLog.logMessage(''.join(self.loglines), 'Processing', Qgis.Info)
        
        return {}
