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

"""
/***************************************************************************
 Geohazard
                                 A QGIS plugin
 Plugin with various tools for landslide analysis and management
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2024-11-29
        copyright            : (C) 2024 by Campus S., Castelli M., Fasciano C., Filipello A.
        email                : andrea.filipello@arpa.piemonte.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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__ = 'Campus S., Castelli M., Fasciano C., Filipello A.'
__date__ = '2024-11-29'
__copyright__ = '(C) 2024 by Campus S., Castelli M., Fasciano C., Filipello A.'

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

__revision__ = '$Format:%H$'

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterRasterLayer
from qgis.core import QgsProcessingParameterNumber
from qgis.core import QgsProcessingParameterRasterDestination
import processing


class LandslideShalstabInputRasterCreator(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterRasterLayer('dtm', 'DTM', defaultValue=None))
        self.addParameter(QgsProcessingParameterNumber('cell_dtm', 'Cell DTM', type=QgsProcessingParameterNumber.Double, defaultValue=10))
        self.addParameter(QgsProcessingParameterNumber('friction_angle__', 'Friction angle_ϕ’ (°)', optional=True, type=QgsProcessingParameterNumber.Double, defaultValue=25))
        self.addParameter(QgsProcessingParameterNumber('depth_z_m', 'Depth_z (m)', optional=True, type=QgsProcessingParameterNumber.Double, defaultValue=1))
        self.addParameter(QgsProcessingParameterNumber('permeability_k_mh', 'Permeability_K (m/h)', optional=True, type=QgsProcessingParameterNumber.Double, defaultValue=0.036))
        self.addParameter(QgsProcessingParameterNumber('unit_weight__nm3', 'Unit Weight_γ (N/m3)', optional=True, type=QgsProcessingParameterNumber.Integer, defaultValue=18000))
        self.addParameter(QgsProcessingParameterNumber('soil_cohesion_nm2', 'Soil cohesion (N/m2)', optional=True, type=QgsProcessingParameterNumber.Integer, defaultValue=10000))
        self.addParameter(QgsProcessingParameterNumber('root_cohesion_nm2', 'Root cohesion (N/m2)', optional=True, type=QgsProcessingParameterNumber.Integer, defaultValue=1000))
        self.addParameter(QgsProcessingParameterRasterDestination('FrictionAngle_', 'Friction angle_ϕ’ (°)', createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterRasterDestination('SoilCohesionNm2', 'Soil cohesion (N/m2)', createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterRasterDestination('RootCohesionNm2', 'Root cohesion (N/m2)', createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterRasterDestination('UnitWeight_Nm3', 'Unit Weight_γ (N/m3)', createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterRasterDestination('Depth_zM', 'Depth_z (m)', createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterRasterDestination('Permeability_kMh', 'Permeability_K (m/h)', createByDefault=True, defaultValue=None))

    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(6, model_feedback)
        results = {}
        outputs = {}

        # Depth_z (m)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['depth_z_m'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['Depth_zM']
        }
        outputs['Depth_zM'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Depth_zM'] = outputs['Depth_zM']['OUTPUT']

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # Permeability_K (m/h)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['permeability_k_mh'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['Permeability_kMh']
        }
        outputs['Permeability_kMh'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Permeability_kMh'] = outputs['Permeability_kMh']['OUTPUT']

        feedback.setCurrentStep(2)
        if feedback.isCanceled():
            return {}

        # Soil cohesion (N/m2)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['soil_cohesion_nm2'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['SoilCohesionNm2']
        }
        outputs['SoilCohesionNm2'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['SoilCohesionNm2'] = outputs['SoilCohesionNm2']['OUTPUT']

        feedback.setCurrentStep(3)
        if feedback.isCanceled():
            return {}

        # Root cohesion (N/m2)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['root_cohesion_nm2'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['RootCohesionNm2']
        }
        outputs['RootCohesionNm2'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['RootCohesionNm2'] = outputs['RootCohesionNm2']['OUTPUT']

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}

        # Friction angle_ϕ’ (°)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['friction_angle__'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['FrictionAngle_']
        }
        outputs['FrictionAngle_'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['FrictionAngle_'] = outputs['FrictionAngle_']['OUTPUT']

        feedback.setCurrentStep(5)
        if feedback.isCanceled():
            return {}

        # Unit Weight_γ (N/m3)
        alg_params = {
            'EXTENT': parameters['dtm'],
            'NUMBER': parameters['unit_weight__nm3'],
            'OUTPUT_TYPE': 5,  # Float32
            'PIXEL_SIZE': parameters['cell_dtm'],
            'TARGET_CRS': parameters['dtm'],
            'OUTPUT': parameters['UnitWeight_Nm3']
        }
        outputs['UnitWeight_Nm3'] = processing.run('native:createconstantrasterlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['UnitWeight_Nm3'] = outputs['UnitWeight_Nm3']['OUTPUT']
        return results

    def name(self):
        return 'Landslide - Shalstab input raster creator'

    def displayName(self):
        return 'Landslide - Shalstab input raster creator'

    def group(self):
        return 'Utility'

    def groupId(self):
        return 'Utility'

    def shortHelpString(self):
        return """<html><body><p><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Generate shalstab input.</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Although most parameters vary spatially across the slope, to assist the user in preparing a quick analysis, this additional tool allows for the generation of constant-value input raster files from the DTM, for use shalstab plugin.</p></body></html></p>
<h2>Parametri in ingresso
</h2>
<h3>DTM</h3>
<p>Raster layer of the DTM</p>
<h3>Cell DTM</h3>
<p>Dimension of the DTM cell (m)</p>
<h3>Friction angle_ϕ’ (°)</h3>
<p>Friction angle of the soil ϕ’ (°)</p>
<h3>Depth_z (m)</h3>
<p>The thickness of the potentially unstable layer (m)</p>
<h3>Permeability_K (m/h)</h3>
<p>The permeability coefficient of the soil Ks (m/h)</p>
<h3>Unit Weight_γ (N/m3)</h3>
<p>The weight per unit volume of the soil γ (N/m3)</p>
<h3>Soil cohesion (N/m2)</h3>
<p>Soil cohesion c_soil (N/m2)</p>
<h3>Root cohesion (N/m2)</h3>
<p>Root cohesion c_root (N/m2)</p>
<h2>Risultati</h2>
<h3>Friction angle_ϕ’ (°)</h3>
<p>Constant raster layer of the friction angle of the soil ϕ’ (°)</p>
<h3>Soil cohesion (N/m2)</h3>
<p>Constant Raster layer of soil cohesion c_soil (N/m2)</p>
<h3>Root cohesion (N/m2)</h3>
<p>Constant raster layer of root cohesion c_root (N/m2)</p>
<h3>Unit Weight_γ (N/m3)</h3>
<p>Constant raster layer of the weight per unit volume of the soil γ (N/m3)</p>
<h3>Depth_z (m)</h3>
<p>Constant raster layer of the thickness of the potentially unstable layer (m)</p>
<h3>Permeability_K (m/h)</h3>
<p>Constant raster layer of the permeability coefficient of the soil Ks (m/h)</p>
<br><p align="right">Autore algoritmo: andrea.filipello@arpa.piemonte.it</p></body></html>"""

    def createInstance(self):
        return LandslideShalstabInputRasterCreator()
