# -*- coding: utf-8 -*-
"""
/***************************************************************************
 QMongo
                                 A QGIS plugin
 connects to REST api with MongoDB  
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2020-07-13
        git sha              : $Format:%H$
        copyright            : (C) 2020 by ATTIC GIS Solutions
        email                : malunje69@gmail.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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction

# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .QMongoConnector_dialog import QMongoDialog
from qgis.core import *
from qgis.gui import *
import os.path
import requests
import json

class QMongo:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.
        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QMongo_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Qgis-Mongo-Connector')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.
        We implement this ourselves since we do not inherit QObject.
        :param message: String for translation.
        :type message: str, QString
        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('QMongo', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.
        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str
        :param text: Text that should be shown in menu items for this action.
        :type text: str
        :param callback: Function to be called when the action is triggered.
        :type callback: function
        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool
        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool
        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str
        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget
        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.
        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/QMongoConnector/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'QGIS MongoDB Connector'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Qgis-Mongo-Connector'),
                action)
            self.iface.removeToolBarIcon(action)
    
    def getLayers(self):
        dts=[]
        self.dlg.listWidget.clear()
        pn_data = requests.get('http://localhost:4000/pnt/layers/') 
        l_data = requests.get('http://localhost:4000/ln/layers/')
        pl_data = requests.get('http://localhost:4000/ply/layers/')

        self.point=[]
        self.line=[]
        self.poly=[]
        
        for i in pn_data.text.split('"'):
    	    if len(i) > 3 :
                dts.append(i)
                self.point.append(i)

        for i in l_data.text.split('"'):
            if len(i) > 3 :
                dts.append(i)
                self.line.append(i)

        
        for i in pl_data.text.split('"'):
            if len(i) > 3 :
                dts.append(i)
                self.poly.append(i)
        self.dlg.listWidget.addItems(dts)
    
    def getRoute(self,name):
        if name in self.point:
            return 'http://localhost:4000/pnt/all/'+name
        elif name in self.line:
            return 'http://localhost:4000/ln/all/'+name
        elif name in self.poly:
            return 'http://localhost:4000/ply/all/'+name

    def createTempLayer(self,layer):
        crs=layer.crs().postgisSrid()
        geom = self.GetGeometry(layer)['geom']
        crt=geom+'?crs='+str(crs)
        new_layer = QgsVectorLayer(crt,layer.name(),'memory')
        new_layer.startEditing()
        fs=layer.dataProvider().fields()
        new_layer.dataProvider().addAttributes(fs)
        new_layer.commitChanges()
        self.addFeatures(new_layer,layer.getFeatures())
        return new_layer

    def addFeatures(self,layer,fts):
        layer.startEditing()
        layer.dataProvider().addFeatures(fts)
        layer.commitChanges()

    def loadLayer(self):
        layer = self.dlg.listWidget.currentItem().text()
        url = self.getRoute(layer)
        data_req = requests.get(url)
        data_layer = data_req.json()
        with open('xx.geojson','w+') as f:
            json.dump(data_layer,f)
        layer = QgsVectorLayer('xx.geojson',layer,'ogr')
        another_layer=self.createTempLayer(layer)
        QgsProject.instance().addMapLayers([layer,another_layer])
    
    def GetGeometry(self,layer):
        if layer.wkbType()==QgsWkbTypes.Point:
            return {'geom':'Point','url':'http://localhost:4000/pnt/entry','raw':'http://localhost:4000/pnt/'}

        if layer.wkbType()==QgsWkbTypes.MultiPoint:
            return {'geom':'Point','url':'http://localhost:4000/pnt/entry','raw':'http://localhost:4000/pnt/'}
        

        if layer.wkbType()==QgsWkbTypes.LineString:
            return {'geom':'LineString','url':'http://localhost:4000/ln/entry','raw':'http://localhost:4000/ln/'}


        if layer.wkbType()==QgsWkbTypes.MultiLineString:
            return {'geom':'MultiLineString','url':'http://localhost:4000/ln/entry','raw':'http://localhost:4000/ln/'}

        if layer.wkbType()==QgsWkbTypes.Polygon:
            return {'geom':'Polygon','url':'http://localhost:4000/ply/entry','raw':'http://localhost:4000/ply/'}

        if layer.wkbType()==QgsWkbTypes.MultiPolygon:
            return {'geom':'MultiPolygon','url':'http://localhost:4000/ply/entry','raw':'http://localhost:4000/ply/'}
        
    def exportLayer(self):
        for layer in self.iface.mapCanvas().layers():
            if layer.name() == self.dlg.comboBox.currentText(): 
                QgsVectorFileWriter.writeAsVectorFormat(layer,(layer.name()+'.geojson'),'UTF-8',layer.crs(),'GeoJSON')
                url = self.GetGeometry(layer)['url']
                file_json = open(layer.name()+'.geojson','r')
                layer_json = json.loads(file_json.read())
                data_req = requests.post(url,json=layer_json)

    def updateLayer(self):
        name=self.dlg.comboBox.currentText()
        url=self.getRoute(name)
        rq = requests.delete(url)
        for layer in self.iface.mapCanvas().layers():
            if layer.name() == name: 
                QgsVectorFileWriter.writeAsVectorFormat(layer,(layer.name()+'.geojson'),'UTF-8',layer.crs(),'GeoJSON')
                url = self.GetGeometry(layer)['url']
                file_json = open(layer.name()+'.geojson','r')
                layer_json = json.loads(file_json.read())
                data_req = requests.post(url,json=layer_json)
                
        
    def RefreshLayers(self):
        self.dlg.comboBox.clear()
        self.dlg.comboBox.clear()
        layers= self.iface.mapCanvas().layers()
        names=[]
        for lay in layers:
            names.append(lay.name())
        self.dlg.comboBox.addItems(names)


        
        
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = QMongoDialog()

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        self.dlg.pushButton.clicked.connect(self.getLayers)
        self.dlg.listWidget.clicked.connect(self.loadLayer)
        self.dlg.pushButton_2.clicked.connect(self.RefreshLayers)
        self.dlg.pushButton_3.clicked.connect(self.exportLayer)
        self.dlg.pushButton_4.clicked.connect(self.updateLayer)