#!/usr/bin/env python3
# Copyright (c) 2024 Stormux
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

"""Base class for Cthulhu plugins using pluggy."""

import os
import logging

import pluggy

# Import pluggy for hook specifications
cthulhu_hookimpl = pluggy.HookimplMarker("cthulhu")


logger = logging.getLogger(__name__)

class Plugin:
    """Base class for Cthulhu plugins."""

    def __init__(self):
        """Initialize the plugin with default attributes."""
        self.app = None
        self.plugin_info = None
        self.module_name = ''
        self.name = ''
        self.version = ''
        self.description = ''
        self._bindings = None
        self._gestureBindings = {}

    def set_app(self, app):
        """Set the application reference."""
        self.app = app

    def set_plugin_info(self, plugin_info):
        """Set plugin information and extract relevant attributes."""
        self.plugin_info = plugin_info
        if plugin_info:
            self.module_name = getattr(plugin_info, 'module_name', '')
            self.name = plugin_info.get_name()
            self.version = plugin_info.get_version()
            self.description = plugin_info.get_description()

    def get_dbus_module_name(self):
        """Return the D-Bus module name for this plugin, or an empty string to opt out."""
        if not self.module_name:
            return ''
        return f"Plugin_{self.module_name}"

    @cthulhu_hookimpl
    def activate(self, plugin=None):
        """Activate the plugin. Override this in subclasses."""
        if plugin is not None and plugin is not self:
            return
        logger.info(f"Activating plugin: {self.name}")

    @cthulhu_hookimpl
    def deactivate(self, plugin=None):
        """Deactivate the plugin. Override this in subclasses."""
        if plugin is not None and plugin is not self:
            return
        logger.info(f"Deactivating plugin: {self.name}")

    def get_bindings(self):
        """Get keybindings for this plugin. Override in subclasses."""
        return self._bindings

    def getPreferencesGUI(self):
        """Return a Gtk widget for plugin preferences, or None if not provided."""
        return None

    def getPreferencesFromGUI(self):
        """Return a dict of plugin preferences from the GUI."""
        return {}

    def registerGestureByString(self, function, name, gestureString, learnModeEnabled=True, globalBinding=True):
        """Register a gesture by string."""
        if self.app:
            api_helper = self.app.getAPIHelper()
            if api_helper:
                binding = api_helper.registerGestureByString(
                    function, 
                    name, 
                    gestureString, 
                    'default', 
                    'cthulhu', 
                    learnModeEnabled, 
                    globalBinding=globalBinding,
                    contextName=self.module_name
                )

                # Also store the binding locally so get_bindings() can use it
                if binding:
                    if not self._bindings:
                        from . import keybindings
                        self._bindings = keybindings.KeyBindings()
                    self._bindings.add(binding)

                return binding
        return None
