from django.shortcuts import render
from django.urls import reverse
import django.db.utils

from .models import *
from .forms import *

from paho.mqtt import client as mqttclient
import json
import random

from supporto import managepassword
from sicurezza.views import *
from logger.views import *
from comunicazioni.views import *
from datetime import date
from configurazione.views import *

# Create your views here.

class mqtt(object):
  def __init__(self):

    self.broker=getConfigurazione('mqtt:broker:address')
    self.port = int(getConfigurazione('mqtt:broker:port'))
    self.username = getConfigurazione('mqtt:broker:username')
    self.password = getConfigurazione('mqtt:broker:password')
    self.client_id = f'mqtt-{random.randint(0, 1000)}'

    self.login()

    self.struttura = dict()
    self.struttura['topic'] = 'dashboard'
    self.struttura['demo'] = False # se il valore e' True, l'operazione non va effettuata
    self.struttura['stampa'] = True
    self.struttura['data'] = list()
    self.struttura['risultato'] = list()
    self.struttura['messaggio'] = ''
    self.struttura['successo'] = ''
    self.struttura['nota'] = ''
    self.struttura['clear'] = '' #rimuove i dati inviati se non servono ulteriori elaborazioni
    self.struttura['seriale'] = '' #il contenuto di data e' serializzato
    self.struttura['numero'] = 0 #conta quanti record vanno elaborati
    self.struttura['notifica_numero'] = False #invia notifica se il numero corrisponde alle lavorazioni
  
    # messaggio viene inviato se tutto e' Tru
    self.check=dict()
    self.check['topic'] = False
    self.check['demo'] = False
    self.check['stampa'] = False
    self.check['data'] = False
    self.check['risultato'] = False
    self.check['messaggio'] = False
    self.check['successo'] = False
    self.check['nota'] = False
    self.check['clear'] = False
    self.check['seriale'] = False
    self.check['numero'] = 0
    self.check['notifica_numero'] = False

  def login(self):
    self.client = mqttclient.Client(self.client_id)
    self.client.username_pw_set(self.username,self.password)
    self.client.on_connect = self.on_connect

    try:
      self.client.connect(self.broker,self.port)
      print('Mqtt Connessione Accettata')
    except ConnectionRefusedError as cre:
      print('Mqtt Connessione Rifiutata')
      print(cre)
      self.client = None

  def publish(self,topic,message):
    print('funzione mqtt:publish obsoleta!')
    self.pubblica(topic,message)

  def pubblica(self,_topic=None,messaggio=None,struttura=None):
    print('reconnecting',self.client.reconnect())

    if _topic:
      print('assegnazione topic da parametro')
      t = _topic
    else:
      print('assegnazione topic da interna')
      t = self.struttura['topic']

    if messaggio:
      print('assegnazione messaggio esterno')
      self.struttura['Messaggio'] = messaggio

    j = None
    if struttura:
      if 'data' in struttura:
        struttura['numero'] = len(struttura['data'])
      j = json.dumps(struttura)
    else:
      if 'data' in self.struttura:
        self.struttura['numero'] = len(self.struttura['data'])
      j = json.dumps(self.struttura)
   
    print('modulo mqtt')
    print('topic:',t)
    print('messaggio:',j)

    result = self.client.publish(t,j)
    
    if result:
      return True
    return False

  def topic(self,_topic=None):
    if _topic:
      self.struttura['topic'] = _topic

  def richiesta(self,_richiesta=None):
    if _richiesta:
      self.struttura['richiesta'] = _richiesta

  def messaggio(self,_messaggio=None):
    if _messaggio:
      self.struttura['messaggio'] = _messaggio

  def demo(self,_demo=False):
    self.struttura['demo']=_demo

  def stampa(self,_stampa=False):
    self.struttura['stampa']=_stampa

  def clear(self,_clear=False):
    self.struttura['clear'] = _clear

  def seriale(self,_seriale=False):
    self.struttura['seriale']= _seriale

  def data(self,_data=list(),replace=False):
    '''
    questo passaggio contiene il dato da elaborare.
    normalmente e' in una lista su cui si puo' ciclare.
    ora ho deciso 27.01.24 di aggiungere anche la serializzazione
    per verificare 2 teorie:
    1: maggior controllo sul dato passato.
    2: abbassare il tasso di errore negli script
    '''
    if replace and _data:
      self.struttura['data'] = _data
    if data:
      self.struttura['data'].append(data)

  def risultato(self,_risultato=list(),replace=False):
    if replace and _risultato:
      self.struttura['risultato'] = _risultato
    if risultato:
      self.struttura['risultato'].append(risultato)

  def messaggio(self,_messaggio=None):
    if _messaggio:
      self.struttura['messaggio'] = _messaggio

  def successo(self,_successo=None):
    if _successo:
      self.struttura['successo']=_successo

  def build(self,valore,chiave):
    print('warning: utilizzo di {} con valore {}'.format(valore,chiave))
    self.struttura[valore] = chiave

    # verifica che la frase sia una stringa e se lo e' 
    # mette la prima lettera maiuscola
    if type(self.struttura[valore]) == str:
      self.struttura[valore] = self.struttura[valore]
    return self.struttura

  def data(self,valore):
    '''
    appende il valore passato alla struttura di richiesta 'data'.
    devo arrivare a far si che tale struttura non sia disponibile dall'esterno
    '''
    self.struttura['data'].append(valore)
    return self.struttura['data']

  def risultato(self,valore):
    '''
    appende il valore passato alla struttura di risposta 'risultato'
    devo arrivare a far si che tale struttura non sia disponibile dall'esterno
    '''
    self.struttura['risultato'].append(valore)
    return self.struttura['risultato']

  def on_connect(client,userdata,flags,rc):
    print('mqtt on_connect')
    if rc == 0:
      print('mqtt connected')
    else:
      print('mqtt failed')

##########################################

def start():
  broker = getConfigurazione('mqtt:broker:address')
  port = int(getConfigurazione('mqtt:broker:port'))
  username = getConfigurazione('mqtt:broker:username')
  password = getConfigurazione('mqtt:broker:password')

  topic = 'dashboard'
  client_id = f'mqtt-{random.randint(0, 1000)}'

  def on_connect(client,userdata,flags,rc):
    print('mqtt on_connect')
    if rc == 0:
      print('mqtt connected')
    else:
      print('mqtt failed')

  client = mqttclient.Client(client_id)
  client.username_pw_set(username,password)
  client.on_connect = on_connect

  try:
    client.connect(broker,port)
  except ConnectionRefusedError as cre:
    print('Connessione rifiutata')
    print(cre)
    client = None

  return client

def publish(client,topic,message):
  if client:
    client.reconnect()
    result = client.publish(topic,message)
    print('mqtt result:',result)
  else:
    print('mqtt failed to send')

def publishMessaggi(client,message):
  if client:
    client.reconnect()
    result = client.publish('Messaggi',json.dumps({'me':message}))
    print('mqtt result:',result)
  else:
    print('mqtt failed to send')

def command(request):
  data = {}
  return render(request,'',data)


def MqttList(request):
  session = getSessionParms(request)
  userauth = session['_userauth_']
  filtro2edit = session['_mqtt2edit_']
  request.session['from']='filtro:MqttList'

  utenteautorizzato = User.objects.get(pk=userauth)

  value={}

  value['utenteautorizzato'] = utenteautorizzato
  value['navbar'] = True

  print("livello autorizzazione",utenteautorizzato.securitylevel_id)
  securitylevel = getSecurityLevel(utenteautorizzato.securitylevel_id)
  securityrow = getSecurityRow(utenteautorizzato.securitylevel_id)
  securitylist =  getSecurityList(securityrow)
  value['securitylist'] = securitylist
  value['securityrow'] = securityrow
  value['securityrowLen'] = len(securityrow)

  mqttlist = MqttService.objects.order_by('nome')
  value['mqtt'] = mqttlist

  if request.method=="POST":

    if "Nuovo Filtro" in request.POST:
      print('nuovo filtro')
      request.session['_mqtt2edit_'] = 0
      return  HttpResponseRedirect(reverse('Mqtt:MqttEdit',args={}))

    if "edit" in request.POST:
      print('id da editare',request.POST['edit'])
      request.session['_mqtt2edit_'] = request.POST['edit']

      return HttpResponseRedirect(reverse('Mqtt:MqttEdit',args={}))

    '''
    if "disable" in request.POST :
      print('id da disattivare',request.POST['disable'])
      idpost = request.POST['disable']
      f = Filtro.objects.get(pk=idpost)
      f.enabled=False
      f.save()

    if "enable" in request.POST:
      print('id da attivare',request.POST['enable'])
      idpost = request.POST['enable']
      f = Filtro.objects.get(pk=idpost)
      f.enabled=True
      f.save()

    if "delete" in request.POST:
      print('id da cancellare',request.POST['delete'])
      idpost = request.POST['delete']
      f = Filtro.objects.get(pk=idpost)
      f.delete()
    '''

  return render(request,"Mqtt.List.html",value)

def MqttEdit(request):
  pass
