from typing import Dict, Any, List, Tuple

from enmapbox.typeguard import typechecked
from enmapboxprocessing.enmapalgorithm import EnMAPProcessingAlgorithm, Group
from qgis.core import (QgsProcessingContext, QgsProcessingFeedback)


@typechecked
class SaveLibraryAsGeoJsonAlgorithm(EnMAPProcessingAlgorithm):
    P_LIBRARY, _LIBRARY = 'library', 'Spectral library'
    P_OUTPUT_FILE, _OUTPUT_FILE = 'outputFile', 'Output file'

    @classmethod
    def displayName(cls) -> str:
        return 'Save spectral library as GeoJSON file'

    def shortDescription(self) -> str:
        return 'Save a spectral library as a human-readable GeoJSON text file. ' \
               'All binary profile fields will be converted into human-readable dictionary strings.'

    def helpParameters(self) -> List[Tuple[str, str]]:
        return [
            (self._LIBRARY, 'The spectral library to be stored as GeoJSON text file.'),
            (self._OUTPUT_FILE, 'Destination GeoJSON file.')
        ]

    def group(self):
        return Group.ExportData.value

    def initAlgorithm(self, configuration: Dict[str, Any] = None):
        self.addParameterVectorLayer(self.P_LIBRARY, self._LIBRARY)
        self.addParameterFileDestination(self.P_OUTPUT_FILE, self._OUTPUT_FILE, 'GeoJSON (*.geojson)')

    def processAlgorithm(
        self, parameters: Dict[str, Any], context: QgsProcessingContext, feedback: QgsProcessingFeedback
    ) -> Dict[str, Any]:
        library = self.parameterAsVectorLayer(parameters, self.P_LIBRARY, context)
        filename = self.parameterAsFileOutput(parameters, self.P_OUTPUT_FILE, context)

        with open(filename + '.log', 'w') as logfile:
            feedback, feedback2 = self.createLoggingFeedback(feedback, logfile)
            self.tic(feedback, parameters, context)

            from enmapbox.qgispluginsupport.qps.speclib.io.geojson import GeoJSONSpectralLibraryWriter

            writer = GeoJSONSpectralLibraryWriter(crs=library.crs())
            r = writer.writeFeatures(filename, library.getFeatures(), feedback=feedback)
            if isinstance(r, list) and len(r) > 0:
                result = {self.P_OUTPUT_FILE: r[0].as_posix()}
            else:
                result = {}

            self.toc(feedback, result)
        return result
