import time
import threading
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class RostaingWatcher(FileSystemEventHandler):
    """File system watcher for documents and local datasets."""
    def __init__(self, callback_function, directory, logger=None):
        self.callback_function = callback_function
        self.directory = directory
        self.logger = logger
        self.observer = Observer()

    def _log(self, msg, level="info"):
        if self.logger: self.logger(msg, level)
        else: print(msg)

    def start(self):
        self.observer.schedule(self, self.directory, recursive=True)
        self.observer.start()
        self._log(f"RostaingAgent Watcher (Disk) enabled on: {self.directory}")

    def stop(self):
        self.observer.stop()
        self.observer.join()

    def on_created(self, event):
        if not event.is_directory:
            self._log(f"New file detected: {event.src_path}")
            self.callback_function(event.src_path)

    def on_modified(self, event):
        if not event.is_directory:
            self._log(f"File modified: {event.src_path}")
            self.callback_function(event.src_path)

class PollingWatcher:
    """Polling watcher for DB, Web, and Dynamic Callable DataFrames."""
    def __init__(self, callback_function, source_config, interval=60, logger=None):
        self.callback_function = callback_function
        self.source_config = source_config
        self.interval = interval
        self.running = False
        self.thread = None
        self.logger = logger

    def _log(self, msg, level="info"):
        if self.logger: self.logger(msg, level)
        else: print(msg)

    def start(self):
        self.running = True
        self.thread = threading.Thread(target=self._loop)
        self.thread.daemon = True
        self.thread.start()
        self._log(f"Polling Watcher (DB/Web/DataFrame) enabled (Interval: {self.interval}s)")

    def stop(self):
        self.running = False
        if self.thread: self.thread.join()

    def _loop(self):
        while self.running:
            try: 
                self.callback_function(self.source_config)
            except Exception as e: 
                self._log(f"Polling Error: {e}", "error")
            time.sleep(self.interval)