# -*- coding: utf-8 -*-
import subprocess
import os
import sys
import stat
import processing
import gc

"""
/***************************************************************************
 Networks
                                 A QGIS plugin
 Networks
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-02-26
        copyright            : (C) 2018 by Patrick Palmier
        email                : patrick.palmier@cerema.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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__ = 'Patrick Palmier'
__date__ = '2018-02-26'
__copyright__ = '(C) 2018 by Patrick Palmier'

__revision__ = '$Format:%H$'

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import QgsProcessingAlgorithm, QgsProcessingParameterFile, \
                     QgsProcessingParameterFileDestination, QgsProcessingParameterBoolean


class CalculMint(QgsProcessingAlgorithm):

    RESEAU = 'RESEAU'
    MATRICE = 'MATRICE'
    PARAMETRES = 'PARAMETRES'
    SORTIE = 'SORTIE'
    DOWNLOAD = 'DOWNLOAD'
    WAIT = 'WAIT'

    def initAlgorithm(self, config):
        self.addParameter(
            QgsProcessingParameterFile(self.RESEAU, self.tr('Mint network'))
        )
        self.addParameter(
            QgsProcessingParameterFile(self.MATRICE, self.tr('Mint matrix'))
        )
        self.addParameter(
            QgsProcessingParameterFile(self.PARAMETRES, self.tr('Mint parameters'))
        )
        self.addParameter(
            QgsProcessingParameterFileDestination(
                self.SORTIE,
                self.tr('Output'),
                "*.txt"
            )
        )
        self.addParameter(
            QgsProcessingParameterBoolean(
                self.DOWNLOAD,
                self.tr('Accept to download Mint binary from Github'),
                False
            )
        )
        self.addParameter(
            QgsProcessingParameterBoolean(
                self.WAIT,
                self.tr('Force waiting the end of calculations'),
                True
            )
        )

    def processAlgorithm(self, parameters, context, feedback):
        reseau = self.parameterAsFile(parameters, self.RESEAU, context)
        matrice = self.parameterAsFile(parameters, self.MATRICE, context)
        parametres = self.parameterAsFile(parameters, self.PARAMETRES, context)
        sortie = os.path.splitext(self.parameterAsFileOutput(parameters, self.SORTIE, context))[0]
        download = self.parameterAsBool(parameters, self.DOWNLOAD, context)
        wait = self.parameterAsBool(parameters, self.WAIT, context)

        if download:
            feedback.setProgressText(self.tr("Downloading Mint_console binary"))
            processing.run("native:filedownloader", {
                'URL': 'https://github.com/crocovert/Mintc/raw/main/bin/x64/Release/Mintc.exe',
                'OUTPUT': os.path.join(os.path.dirname(__file__), "Mint_console.exe")
            })
            feedback.setProgressText(self.tr("Mint_console downloaded successfully"))

        if sys.platform.startswith('win'):
            prog = os.path.join(os.path.dirname(__file__), "Mint_console.exe")
            cmd = [prog, reseau, matrice, sortie, parametres]
        elif sys.platform.startswith('linux'):
            prog = os.path.join(os.path.dirname(__file__), "Mint_console.exe")
            if os.path.exists(prog):
                st = os.stat(prog)
                os.chmod(prog, st.st_mode | stat.S_IEXEC)
            cmd = ["mono", prog, reseau, matrice, sortie, parametres]
        else:
            feedback.reportError(self.tr("Unsupported platform"), fatalError=True)
            return {}

        feedback.setProgressText(self.tr("Mint calculations... This may take some time"))

        # B603: Command is built from controlled user parameters via QGIS
        musliw_test = subprocess.Popen(cmd)  #nosec B603

        if wait:
            musliw_test.wait()

        gc.collect()
        return {'SORTIE': sortie}

    def name(self):
        return 'mint_calculation'

    def displayName(self):
        return self.tr('Mint computation')

    def group(self):
        return self.tr('Computations')

    def groupId(self):
        return 'Computations'

    def tr(self, string):
        return QCoreApplication.translate('CalculMint', string)

    def shortHelpString(self):
        return self.tr("""
        Perform a calculation of multimodal assignment with a frequency based algorithm (Mint)
        Can download the Mint_console.exe binary...
        """)

    def createInstance(self):
        return CalculMint()