#!/usr/bin/env python3
import faulthandler
import signal
import sys
from uuid import uuid4 as uuid

from PyQt5.QtWidgets import QApplication
from peewee import AutoField, Model, TextField
from playhouse.sqlite_ext import SqliteExtDatabase
from PyQt5.QtCore import QObject, QThread, QTimer

# SETUP QUITTING ON CTRL+C
signal.signal(signal.SIGINT, quit)

# SETUP FAULTHANDLER
faulthandler.enable(file=sys.stderr, all_threads=True)


db = SqliteExtDatabase(
    "/tmp/tdb.sqlite3",
    pragmas={  # see https://www.sqlite.org/pragma.html
        "auto_vacuum": 1,
        "busy_timeout": 5000,
        "cache_size": round(-64e3),
        "foreign_keys": 1,
        "ignore_check_constraints": 0,
        "journal_mode": "wal",
        "synchronous": 0,
    },
    timeout=5
)


class BaseModel(Model):
    """A base model that will use our Sqlite database."""

    class Meta:
        global db
        database = db


class Data(BaseModel):
    id = AutoField(primary_key=True, unique=True, null=False)
    data = TextField(null=True, default=lambda: uuid().hex)


models_reference = {
    "data": Data,
}

db.connect()
db.create_tables(list(models_reference.values()))


class Threaded(QObject):
    def __init__(self):
        super().__init__()
        self._timer = QTimer()

    @db.connection_context()
    # @db.atomic()
    def start(self):
        # for data in Data.select():
        while True:
            for data in list(Data.select().order_by(Data.id.desc()))[:1] + [Data()]:
                data.save()
                print(str(int(QThread.currentThreadId())), data.id, flush=True)
                # QThread.msleep(2000)
            for i in range(2):
                data = Data()
                data.save()
                print(str(int(QThread.currentThreadId())), data.id, flush=True)
                # QThread.msleep(2000)


components = {1: Threaded()}
threads = {}
for component_name in components:
    threads[component_name] = QThread()
    threads[component_name].setTerminationEnabled(True)
    components[component_name].moveToThread(threads[component_name])
for component_name, thread in threads.items():
    component = components[component_name]
    thread.started.connect(component.start)
    thread.start()
    QApplication.processEvents()
    # QThread.msleep(1000)
    QApplication.processEvents()
while True:
    for data in list(Data.select().order_by(Data.id.desc()))[:1] + [Data()]:
        data.save()
        # print(str(int(QThread.currentThreadId())), data.id, flush=True)
        print("main", data.id, flush=True)
        # QThread.msleep(2000)
    for i in range(2):
        data = Data()
        data.save()
        # print(str(int(QThread.currentThreadId())), data.id, flush=True)
        print("main", data.id, flush=True)
        # QThread.msleep(2000)
