from PySide6.QtCore import QFileSystemWatcher, QObject, Signal

class FileWatcher(QObject):
    """
    FileWatcher class for monitoring file and directory changes.

    This class automatically detects changes in specific files or directories and provides notifications.

    Attributes
    ----------
    file_changed : Signal
        Signal emitted when a file is changed.
    directory_changed : Signal
        Signal emitted when a directory is changed.

    Methods
    -------
    add_path(path)
        Adds a file or directory to the watch list.
    remove_path(path)
        Removes a file or directory from the watch list.
    get_watched_paths()
        Returns all currently watched paths (files and directories).
    get_watched_files()
        Returns all currently watched files.
    get_watched_directories()
        Returns all currently watched directories.
    remove_all_paths()
        Removes all paths from the watch list.
    """

    file_changed = Signal(str)
    directory_changed = Signal(str)

    def __init__(self):
        """
        Initializes the FileWatcher object.
        """
        super().__init__()
        self.watcher = QFileSystemWatcher()
        self.watcher.fileChanged.connect(self.file_changed)
        self.watcher.directoryChanged.connect(self.directory_changed)

    def add_path(self, path):
        """
        Adds a file or directory to the watch list.

        Parameters
        ----------
        path : str
            The path of the file or directory to watch.

        Returns
        -------
        bool
            Whether the path was successfully added.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> result = watcher.add_path("/path/to/file_or_directory")
        >>> if result:
        >>>     print("Watch started")
        >>> else:
        >>>     print("Failed to start watching")
        """
        return self.watcher.addPath(path)

    def remove_path(self, path):
        """
        Removes a file or directory from the watch list.

        Parameters
        ----------
        path : str
            The path of the file or directory to remove.

        Returns
        -------
        bool
            Whether the path was successfully removed.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> result = watcher.remove_path("/path/to/file_or_directory")
        >>> if result:
        >>>     print("Successfully stopped watching")
        >>> else:
        >>>     print("Failed to stop watching")
        """
        return self.watcher.removePath(path)

    def get_watched_paths(self):
        """
        Returns all currently watched paths (files and directories).

        Returns
        -------
        list of str
            All currently watched paths.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> paths = watcher.get_watched_paths()
        >>> print("Watched paths:", paths)
        """
        return self.watcher.files() + self.watcher.directories()

    def get_watched_files(self):
        """
        Returns all currently watched files.

        Returns
        -------
        list of str
            All currently watched files.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> files = watcher.get_watched_files()
        >>> print("Watched files:", files)
        """
        return self.watcher.files()

    def get_watched_directories(self):
        """
        Returns all currently watched directories.

        Returns
        -------
        list of str
            All currently watched directories.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> directories = watcher.get_watched_directories()
        >>> print("Watched directories:", directories)
        """
        return self.watcher.directories()

    def remove_all_paths(self):
        """
        Removes all paths from the watch list.

        Returns
        -------
        bool
            Whether all paths were successfully removed.

        Examples
        --------
        >>> watcher = FileWatcher()
        >>> result = watcher.remove_all_paths()
        >>> if result:
        >>>     print("Successfully removed all paths")
        >>> else:
        >>>     print("Failed to remove all paths")
        """
        return self.watcher.removePaths(self.get_watched_paths())
