import os
import mysql.connector
from mysql.connector import Error
from datetime import datetime


class FileSystemToMySQL:
    def __init__(self, host, port,user, password, database):
        self.host = host
        self.port=port
        self.user = user
        self.password = password
        self.database = database
        self.connection = None

    def connect(self):
        try:
            self.connection = mysql.connector.connect(
                host=self.host,
                port=self.port,
                user=self.user,
                password=self.password,
                database=self.database
            )
            if self.connection.is_connected():
                print("Connected to MySQL database")
                self._initialize_database()
        except Error as e:
            print(f"Error connecting to MySQL: {e}")

    def _initialize_database(self):
        cursor = self.connection.cursor()

        # Create tables if they don't exist
        cursor.execute("""
        CREATE TABLE IF NOT EXISTS folders (
            id INT AUTO_INCREMENT PRIMARY KEY,
            path VARCHAR(767) NOT NULL,
            name VARCHAR(255) NOT NULL,
            parent_id INT NULL,
            created_at DATETIME NOT NULL,
            updated_at DATETIME NOT NULL,
            FOREIGN KEY (parent_id) REFERENCES folders(id) ON DELETE CASCADE,
            UNIQUE (path)
        )
        """)

        cursor.execute("""
        CREATE TABLE IF NOT EXISTS files (
            id INT AUTO_INCREMENT PRIMARY KEY,
            folder_id INT NOT NULL,
            name VARCHAR(255) NOT NULL,
            size INT NOT NULL,
            created_at DATETIME NOT NULL,
            updated_at DATETIME NOT NULL,
            FOREIGN KEY (folder_id) REFERENCES folders(id) ON DELETE CASCADE,
            UNIQUE (folder_id, name)
        )
        """)

        self.connection.commit()
        cursor.close()

    def _get_folder_id(self, folder_path):
        cursor = self.connection.cursor()
        cursor.execute("SELECT id FROM folders WHERE path = %s", (folder_path,))
        result = cursor.fetchone()
        cursor.close()
        return result[0] if result else None

    def _insert_folder(self, folder_path, parent_id=None):
        folder_name = os.path.basename(folder_path)
        now = datetime.now()

        cursor = self.connection.cursor()
        cursor.execute("""
        INSERT INTO folders (path, name, parent_id, created_at, updated_at)
        VALUES (%s, %s, %s, %s, %s)
        ON DUPLICATE KEY UPDATE updated_at = %s
        """, (folder_path, folder_name, parent_id, now, now, now))

        folder_id = cursor.lastrowid
        if folder_id == 0:  # If it was an update
            folder_id = self._get_folder_id(folder_path)

        self.connection.commit()
        cursor.close()
        return folder_id

    def store_file(self, file_path, folder_path):
        try:
            # First ensure the folder exists
            folder_id = self._insert_folder(folder_path)

            # Read file content
            with open(file_path, 'rb') as file:
                file_content = file.read()

            file_name = os.path.basename(file_path)
            file_size = os.path.getsize(file_path)
            now = datetime.now()

            cursor = self.connection.cursor()
            cursor.execute("""
            INSERT INTO files (folder_id, name,  size, created_at, updated_at)
            VALUES (%s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE 
                size = VALUES(size),
                updated_at = VALUES(updated_at)
            """, (folder_id, file_name, file_size, now, now))

            self.connection.commit()
            cursor.close()
            print(f"Stored/updated file: {file_name} in folder: {folder_path}")
        except Error as e:
            print(f"Error storing file {file_path}: {e}")

    def store_directory(self, directory_path, parent_folder_path=None):
        try:
            # Ensure the parent folder exists
            parent_id = None
            if parent_folder_path:
                parent_id = self._insert_folder(parent_folder_path)

            # Store the current directory
            dir_id = self._insert_folder(directory_path, parent_id)

            # Store all files in the directory
            for item in os.listdir(directory_path):
                full_path = os.path.join(directory_path, item)
                if os.path.isfile(full_path):
                    self.store_file(full_path, directory_path)
                elif os.path.isdir(full_path):
                    self.store_directory(full_path, directory_path)

            print(f"Stored directory: {directory_path}")
        except Error as e:
            print(f"Error storing directory {directory_path}: {e}")

    def close(self):
        if self.connection and self.connection.is_connected():
            self.connection.close()
            print("MySQL connection closed")


# Example usage
if __name__ == "__main__":
    # Database configuration
    db_config = {
        'host': '192.168.1.76',
        'port': '3307',
        'user': 'root',
        'password': 'Vlado9674+',
        'database': 'file_storage_db'
    }

    # Initialize the file system storage
    fs_storage = FileSystemToMySQL(**db_config)
    fs_storage.connect()

    # Store a single file
   # fs_storage.store_file('/path/to/your/file.txt', '/path/to/your')

    # Store an entire directory
    fs_storage.store_directory(r'u:\Dropbox\!!!Days\Downloads Z230')

    # Close the connection
    fs_storage.close()