"""
Model exported as python.
Name : num_cavi_su_infrastruttua
Group : Script personalizzati
With QGIS : 32809
"""

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterFeatureSource
from qgis.core import QgsProcessingParameterFeatureSink
import processing


class Num_cavi_su_infrastruttua(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterFeatureSource('cavi_4326', 'CAVI (4326)', types=[QgsProcessing.TypeVectorAnyGeometry], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSource('infrastruttura_4326', 'INFRASTRUTTURA (4326)', types=[QgsProcessing.TypeVectorAnyGeometry], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('InfrastrutturaConNcavi', 'INFRASTRUTTURA CON NCAVI', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, supportsAppend=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(7, model_feedback)
        results = {}
        outputs = {}

        # ID progressivo infrastruttura
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'id_infr',
            'FIELD_PRECISION': 0,
            'FIELD_TYPE': 1,  # Intero (32 bit)
            'FORMULA': '$id',
            'INPUT': parameters['infrastruttura_4326'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['IdProgressivoInfrastruttura'] = processing.run('native:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}
        
        # ID progressivo cavi
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'id_cav',
            'FIELD_PRECISION': 0,
            'FIELD_TYPE': 1,  # Intero (32 bit)
            'FORMULA': '$id',
            'INPUT': parameters['cavi_4326'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['IdProgressivoCavi'] = processing.run('native:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Buffer cavi
        alg_params = {
            'DISSOLVE': False,
            'DISTANCE': 1e-07,
            'END_CAP_STYLE': 0,  # Arrotondato
            'INPUT': outputs['IdProgressivoCavi']['OUTPUT'],
            'JOIN_STYLE': 0,  # Arrotondato
            'MITER_LIMIT': 2,
            'SEGMENTS': 5,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['BufferCavi'] = processing.run('native:buffer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Ripara geometrie infrastruttura
        alg_params = {
            'INPUT': outputs['IdProgressivoInfrastruttura']['OUTPUT'],
            'METHOD': 1,  # Struttura
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RiparaGeometrieInfrastruttura'] = processing.run('native:fixgeometries', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}
        
        # Esplodi linee infrastruttura
        alg_params = {
            'INPUT': outputs['RiparaGeometrieInfrastruttura']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['EsplodiLineeInfrastruttura'] = processing.run('native:explodelines', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Associa id_cav sull'infrastruttura
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['EsplodiLineeInfrastruttura']['OUTPUT'],
            'JOIN': outputs['BufferCavi']['OUTPUT'],
            'JOIN_FIELDS': ['id_cav'],
            'METHOD': 0,  # Crea elementi separati per ciascun elemento corrispondente (uno-a-molti)
            'PREDICATE': [1,5,4],  # contiene,sono contenuti,sovrappone
            'PREFIX': '',
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['AssociaId_cavSullinfrastruttura'] = processing.run('native:joinattributesbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Aggrega per id dell'infrastruttura
        alg_params = {
            'AGGREGATES': [{'aggregate': 'first_value','delimiter': ',','input': '"id_infr"','length': 250,'name': 'id_layer1','precision': 0,'sub_type': 0,'type': 6,'type_name': 'double precision'},{'aggregate': 'concatenate','delimiter': ',','input': 'to_string("id_cav")','length': 10000,'name': 'id_layer2','precision': 0,'sub_type': 0,'type': 10,'type_name': 'text'}],
            'GROUP_BY': 'id_infr',
            'INPUT': outputs['AssociaId_cavSullinfrastruttura']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['AggregaPerIdDellinfrastruttura'] = processing.run('native:aggregate', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Riorganizza campi infrastruttura
        alg_params = {
            'FIELDS_MAPPING': [{'expression': '"id_layer1"','length': 250,'name': 'id_layer1','precision': 0,'sub_type': 0,'type': 10,'type_name': 'text'},{'expression': 'if(\r\nright("id_layer2",1) = \',\',\r\narray_to_string(array_distinct(string_to_array(left("id_layer2", length("id_layer2")-1),\',\'))), \r\narray_to_string(array_distinct(string_to_array("id_layer2",\',\'))))','length': 10000,'name': 'id_layer2','precision': 0,'sub_type': 0,'type': 10,'type_name': 'text'},{'expression': 'if(right("id_layer2",1) = \',\', \r\narray_length(array_distinct(string_to_array("id_layer2",\',\')))-1, \r\narray_length(array_distinct(string_to_array("id_layer2",\',\'))))','length': 10,'name': 'n_overlaps','precision': 0,'sub_type': 0,'type': 2,'type_name': 'integer'}],
            'INPUT': outputs['AggregaPerIdDellinfrastruttura']['OUTPUT'],
            'OUTPUT': parameters['InfrastrutturaConNcavi']
        }
        outputs['RiorganizzaCampiInfrastruttura'] = processing.run('native:refactorfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['InfrastrutturaConNcavi'] = outputs['RiorganizzaCampiInfrastruttura']['OUTPUT']
        return results

    def name(self):
        return 'num_cavi_su_infrastruttura'

    def displayName(self):
        return 'num_cavi_su_infrastruttura'

    def group(self):
        return 'Script personalizzati'

    def groupId(self):
        return 'script_personalizzati'

    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:9pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></p>
<br><p align="right">Autore algoritmo: mpeppucci</p></body></html>"""

    def createInstance(self):
        return Num_cavi_su_infrastruttua()
