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

"""
***************************************************************************
    SagaUtils.py
    ---------------------
    Date                 : August 2012
    Copyright            : (C) 2012 by Victor Olaya
    Email                : volayaf at gmail dot com
***************************************************************************
*                                                                         *
*   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__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'

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

__revision__ = '$Format:%H$'

import os
import stat
import subprocess

from PyQt4.QtCore import QCoreApplication
from qgis.core import QgsApplication
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.ProcessingLog import ProcessingLog
from processing.tools.system import isWindows, isMac, userFolder

SAGA_LOG_COMMANDS = 'SAGA_LOG_COMMANDS'
SAGA_LOG_CONSOLE = 'SAGA_LOG_CONSOLE'
SAGA_FOLDER = 'SAGA_FOLDER'
SAGA_IMPORT_EXPORT_OPTIMIZATION = 'SAGA_IMPORT_EXPORT_OPTIMIZATION'


def sagaBatchJobFilename():
    if isWindows():
        filename = 'saga_batch_job.bat'
    else:
        filename = 'saga_batch_job.sh'

    batchfile = userFolder() + os.sep + filename

    return batchfile


def findSagaFolder():
    folder = None
    if isMac():
        testfolder = os.path.join(QgsApplication.prefixPath(), 'bin')
        if os.path.exists(os.path.join(testfolder, 'saga_cmd')):
            folder = testfolder
        else:
            testfolder = '/usr/local/bin'
            if os.path.exists(os.path.join(testfolder, 'saga_cmd')):
                folder = testfolder
    elif isWindows():
        testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()), 'saga')
        if os.path.exists(os.path.join(testfolder, 'saga_cmd.exe')):
            folder = testfolder
    return folder


def sagaPath():
    folder = ProcessingConfig.getSetting(SAGA_FOLDER)
    if folder is None or folder == '':
        folder = findSagaFolder()
        if folder is not None:
            ProcessingConfig.setSettingValue(SAGA_FOLDER, folder)
    return folder or ''


def sagaDescriptionPath():
    return os.path.join(os.path.dirname(__file__), 'description')


def createSagaBatchJobFileFromSagaCommands(commands):

    fout = open(sagaBatchJobFilename(), 'w')
    if isWindows():
        fout.write('set SAGA=' + sagaPath() + '\n')
        fout.write('set SAGA_MLB=' + sagaPath() + os.sep
                   + 'modules' + '\n')
        fout.write('PATH=PATH;%SAGA%;%SAGA_MLB%\n')
    elif isMac():
        fout.write('export SAGA_MLB=' + sagaPath()
                   + '/../lib/saga\n')
        fout.write('export PATH=' + sagaPath() + ':$PATH\n')
    else:
        pass
    for command in commands:
        fout.write('saga_cmd ' + command.encode('utf8') + '\n')

    fout.write('exit')
    fout.close()

_installedVersion = None
_installedVersionFound = False


def getSagaInstalledVersion(runSaga=False):
    global _installedVersion
    global _installedVersionFound

    maxRetries = 5
    retries = 0
    if _installedVersionFound and not runSaga:
        return _installedVersion

    if isWindows():
        commands = [os.path.join(sagaPath(), "saga_cmd.exe"), "-v"]
    elif isMac():
        commands = [os.path.join(sagaPath(), "saga_cmd -v")]
    else:
        # for Linux use just one string instead of separated parameters as the list
        # does not work well together with shell=True option
        # (python docs advices to use subprocess32 instead of python2.7's subprocess)
        commands = ["saga_cmd -v"]
    while retries < maxRetries:
        proc = subprocess.Popen(
            commands,
            shell=True,
            stdout=subprocess.PIPE,
            stdin=open(os.devnull),
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        ).stdout
        try:
            lines = proc.readlines()
            for line in lines:
                if line.startswith("SAGA Version:"):
                    _installedVersion = line[len("SAGA Version:"):].strip().split(" ")[0]
                    _installedVersionFound = True
                    return _installedVersion
            return None
        except IOError:
            retries += 1
        except:
            return None

    return _installedVersion


def executeSaga(progress):
    if isWindows():
        command = ['cmd.exe', '/C ', sagaBatchJobFilename()]
    else:
        os.chmod(sagaBatchJobFilename(), stat.S_IEXEC
                 | stat.S_IREAD | stat.S_IWRITE)
        command = [sagaBatchJobFilename()]
    loglines = []
    loglines.append(QCoreApplication.translate('SagaUtils', 'SAGA execution console output'))
    proc = subprocess.Popen(
        command,
        shell=True,
        stdout=subprocess.PIPE,
        stdin=open(os.devnull),
        stderr=subprocess.STDOUT,
        universal_newlines=True,
    ).stdout
    try:
        for line in iter(proc.readline, ''):
            if '%' in line:
                s = ''.join([x for x in line if x.isdigit()])
                try:
                    progress.setPercentage(int(s))
                except:
                    pass
            else:
                line = line.strip()
                if line != '/' and line != '-' and line != '\\' and line != '|':
                    loglines.append(line)
                    progress.setConsoleInfo(line)
    except:
        pass
    if ProcessingConfig.getSetting(SAGA_LOG_CONSOLE):
        ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)