"""Functions to connect to and monitor serial"""

import sys
import datetime
import json

import serial

from src.in_io import sqlite as pysql
from src.in_io import in_io as inio


def readserial(comport: str, baudrate: int, handler):
    """Function to read value from a serial port
    Assumes it is a json formatted string

    Parameters
    ----------
    comport : str
        the com port to connect to
    baudrate : int
        the baud rate of the connection
    timestamp : bool, optional
        Whether to add timestamp to data, by default False
    """
    ser = serial.Serial(
        comport, baudrate, timeout=0.1
    )  # 1/timeout is the frequency at which the port is read

    try:
        while True:

            ser_in = ser.readline().decode().strip()

            if "{" in ser_in:
                try:
                    data = json.loads(ser_in)
                except json.JSONDecodeError as e:
                    print("Not a valid JSON for database")
                    return

                ct = datetime.datetime.now()
                ctdata = {"timestamp": int(ct.timestamp()), **data}
                # This saves to SQL
                if "sqlite" in handler.save_dict:
                    # get devinfo
                    tab_known, dev_inf = pysql.get_device_info(
                        handler.save_dict["sqlite"]["cursor"], data["inator"]
                    )
                    if tab_known:
                        # only attempt to save to SQL if known
                        # remove inator as not needed now
                        del ctdata["inator"]
                        # get the data to id key
                        key_dict = pysql.get_data_id_key(
                            handler.save_dict["sqlite"]["cursor"], dev_inf, ctdata
                        )
                        __ = pysql.insert_dev_log_table(
                            handler.save_dict["sqlite"]["cursor"],
                            dev_inf,
                            ctdata,
                            key_dict,
                        )
                        handler.save_dict["sqlite"]["connection"].commit()

                # This saves to text file
                if "file" in handler.save_dict:
                    inio.save_plain_text(
                        handler.save_dict["file"]["filepath"], ct, data
                    )

                if ("sqlite" not in handler.save_dict) or (
                    "file" not in handler.save_dict
                ):
                    print(f"Recieved {data} at {ct} but no logging set up")
            elif ser_in:
                print(ser_in)
    except KeyboardInterrupt:
        print("Ending Logging")
        sys.exit()
