import sqlite3
import os

#Get this file's path
DIR = os.path.dirname(os.path.abspath(__file__))

DB_LOCATION = os.path.join(DIR, "lanwatch.db")

def get_connection():
    """Return a database connection"""
    connection = sqlite3.connect(DB_LOCATION)
    return connection

def generate_db():
    """Generate db and needed tables (registry table)"""
    with get_connection() as conn:
        cursor :sqlite3.Cursor = conn.cursor()
        registry_query = """
            CREATE TABLE IF NOT EXISTS registry (
                id INTEGER PRIMARY KEY,
                ip VARCHAR(39),
                host VARCHAR(25),
                last_seen TEXT,
                UNIQUE(ip, host)
            )
        """
        cursor.execute(registry_query)

def create_registry(ip:str, host:str, last_seen:str):
    """Create a row in registry table"""
    with get_connection() as conn:
        cursor :sqlite3.Cursor = conn.cursor()
        insert_query = """
            INSERT INTO registry(ip,host,last_seen) 
            VALUES(?,?,?);
        """
        cursor.execute(insert_query, (ip, host, last_seen))

def update_registry(pk:int, ip:str, host:str, last_seen:str):
    """Update a row in registry table"""
    with get_connection() as conn:
        cursor :sqlite3.Cursor = conn.cursor()
        update_query = """
            UPDATE registry SET
            ip=?, host=?, last_seen=?
            WHERE id=?;
        """
        cursor.execute(update_query, (ip, host, last_seen, pk))

def store_registry(ip:str, host:str, last_seen:str):
    """Store (meaning to update or create depending if it exists or not based on ip) a row in registry table"""
    id_exists = ""
    with get_connection() as conn:
        query_check_exists = "SELECT id, host FROM registry WHERE ip = ?;"
        cursor :sqlite3.Cursor = conn.cursor()
        cursor.execute(query_check_exists, (ip, ))
        id_exists = cursor.fetchall()
    if len(id_exists)>0:
        update_registry(id_exists[0][0], ip, id_exists[0][1], last_seen)
    else:
        create_registry(ip, host, last_seen)

def delete_registry(pk:int):
    """Delete a row in registry table"""
    with get_connection() as conn:
        cursor :sqlite3.Cursor = conn.cursor()
        delete_query = """
            DELETE FROM registry where id = ?;
        """
        cursor.execute(delete_query, (pk,))


def get_registry() -> list[dict]:
    """Return all rows in registry table"""
    with get_connection() as conn:
        conn.row_factory = sqlite3.Row #Used to get row to something that can be transformed into a dict
        cursor :sqlite3.Cursor = conn.cursor()
        get_query = """
            SELECT * FROM registry;
        """
        cursor.execute(get_query)
        return [dict(element) for element in cursor.fetchall()]


def clear_registry_table(do_not_recreate=False):
    """Drop registry table"""
    with get_connection() as conn:
        cursor :sqlite3.Cursor = conn.cursor()
        registry_query = """
            DROP TABLE registry;
        """
        cursor.execute(registry_query)
        if not do_not_recreate:
            generate_db()

if __name__ == "__main__":
    generate_db()
    print(f"DB generated at {DB_LOCATION}")
