# python script to receive POST / or GET (to be done) from browser client
# make sute the sys.path.append points to the right packages
import sys, os
sys.path.append('/home/antoniusengbersen/.local/lib/python3.11/site-packages')  
# in case of issues, use the below to figure what is all in the path now...
# it normally fails loading the mariadb.
#output=''
#output += 'sys.version = %s\n' % repr(sys.version)
#output += 'sys.prefix = %s\n' % repr(sys.prefix)
#output += 'sys.path = %s\n' % repr(sys.path)
#output=bytes(output,'utf-8')
#print (output) 

import mariadb
import datetime
from datetime import timedelta 
import json 


def application(environ,start_response):
    status= '200 OK'
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
        status = '500 Internal Server Error'
        
    request_body = environ['wsgi.input'].read(request_body_size)
    html=jsonify(process_request(request_body))
    html=bytes(html,'utf8')
    response_header = [('Content-type','text/html')]
    start_response(status,response_header)
    return [html]
     
def process_request(request):

# the purpose here is to retrieve data from the MariaDB,
# $dbname = 'Haus_sensors'; $dbuser = 'phpuser'; $dbpass = 'php132lK#!'; $dbhost = 'localhost';
# 
# the request is a dict. with "st" (start_time), "et" (end_time), "res"(resolution) values, which are
# set by the requester.  If start_time is 0, approx. the last hour of values will be retrieved
# if start_time = 1, only the last row of values will be retrieved.
# NOTE: times must be in YYYY-MM-DD HH:MM:SS format !
# 
# the return is a string [ {"id",<record_id>, "ti":<datetime>,"OP":<operation>,"t":<temperature>,"h":<humidity>,"l":<threshold>} ,  {etc},  {etc. } ]
  
  l_request=json.loads(request)
  #print ("l_request=")
  #print (l_request)
  match l_request['TYP']:
    case "LUFTE":
      table='Luftentfeuchter'
    case "TEMP":
      table='temperature1'
    case _:
      table=' '
      print ("Error no matching TYP:")
      print (l_request)
        
  if "st" in l_request:
    # we find an start_time
    start_time = l_request["st"]
    if (not((start_time==0) or (start_time==1)) ): 
      start_datetime=datetime.datetime.strptime(start_time,"%Y-%m-%d %H:%M:%S")
      # there must be an end-time if here
      if "et" in l_request:
        end_time = l_request["et"]
        end_datetime=datetime.datetime.strptime(end_time,"%Y-%m-%d %H:%M:%S")
      else:
        # there is a non-zero or non-1 start time but no end_time: 
        # just default to 60 minutes more (back in time)
        one_hour=timedelta(hours=1)
        end_datetime=start_datetime-one_hour
  else:
    # no start_time assume start_time = 0
    # which basically means we also do not look for end time and resolution
    start_time=0
    # after here start_time is either 0,1, or a 'real' time
    # in case of a 'real' time, start_datetime and end_datetime are set.
  if start_time==1:
    # get the last row from the DB
    q_result = retrieve_from_db(1,table)
  elif start_time==0:
    # get the last 60 rows from DB
    q_result = retrieve_from_db(0,table)
  else:
    # retrieve time-span from DB
    q_result = retrieve_from_db(2,table,start_datetime,end_datetime)
  return l_request,q_result
  
# end process_request
  
        
      
def retrieve_from_db(mode,table,
                     start_dt=datetime.datetime.now(),
                     end_dt=datetime.datetime.now()):
                     
#    import datetime
#    from datetime import timedelta
              
    try:
        connect_db=mariadb.connect(
        user="phpuser",
        password="12345678",
        host="localhost",
        port=3306,
        database="Haus_sensors"
        )
        database_connect=True;
    except mariadb.Error as e:
        print(f"error connecting to MariaDB: {e}")
        database_connect=False;
        connect_db.close()
   
    cursor_db=connect_db.cursor()
    if (database_connect): 
      if mode==0:
        # get the last 60 rows from the db: 
        try: 
          statement="select * from "
          statement=statement+table
          statement=statement+" order by record_id desc limit 60" 
          print (statement)    
          cursor_db.execute(statement)
          return cursor_db
        except connect_db.ERROR as e:
            return "Error retrieving entry from database: {e}" 
      elif mode==1:
        # get the last row from the db: 
        try: 
          statement="select * from "
          statement=statement+table
          statement=statement+" order by record_id desc limit 1"     
          cursor_db.execute(statement)
          return cursor_db
        except connect_db.ERROR as e:
          return "Error retrieving entry from database: {e}" 
      else:
        # get the rows between the two times: 
        try: 
          statement="select * from "
          statement=statement+table
          statement=statement + " where mdatetime > %s and mdatatime < %s"  
          data=(end_dt,start_dt)   
          cursor_db.execute(statement,data)
          return cursor_db
        except connect_db.ERROR as e:
          return "Error retrieving entry from database: {e}" 
      
def jsonify(input_data):
  l_request=input_data[0]
  result=input_data[1]
  first_record=True
  for record in result.fetchall():
    if (l_request['TYP']=="LUFTE"): 
      if record[2]=="ON": oper=40
      else: oper=0
    t=record[1].strftime('%Y-%m-%d %H:%M:%S')
    if first_record:
      match l_request['TYP']:
        case "LUFTE":
          answer='[{{"ti":"{:s}","OP":{:d},"t":{:.1f},"h":{:.1f},"l":{:d}}}'.format(t,oper,record[3],record[4],record[5])
        case "TEMP":
          print (t)
          print (type(t))
          print (record[2])
          print (type(record[2]))
          answer='[{{“ti":"{:s}","t":{:.1f}}}'.format(t,record[2])
          print (answer)
          print (type(answer))
        case _:
          print ("jsonify no valid TYP:")
          print (l_request)
          return(1000)      
      first_record=False
    else:
      match l_request['TYP']:
        case "LUFTE":
          answer=answer+',{{"ti":"{:s}","OP":{:d},"t":{:.1f},"h":{:.1f},"l":{:d}}}'.format(t,oper,record[3],record[4],record[5]) 
        case "TEMP":
          answer=answer+',{{"ti":"{:s}","t":{:.1f}}}'.format(t,record[2])
        case _: 
          print ("jsonify 2 no valid TYP:")
          print (l_request)
          return(1000)    
  answer=answer+']'
  return(answer)          
