import functools
import logging
from packaging.version import Version

from defence360agent.feature_management.constants import (
    EXTENSION_DEFAULTS,
    FEATURE_EXT_VARIABLES,
    NATIVE_EXTENSION_NAME,
    NATIVE_FEATURE_MANAGEMENT_PACKAGE_EXTENSION_FILES,
)
from defence360agent.feature_management.utils import reset_features
from defence360agent.subsys.panels.cpanel import cPanel
from defence360agent.subsys.panels.hosting_panel import HostingPanel

logger = logging.getLogger(__name__)


def supported(func):
    """Do not run a function on an unsupported panel"""

    @functools.wraps(func)
    async def wrapper(*args, **kwargs):
        if await is_native_feature_management_supported():
            return await func(*args, **kwargs)
        logger.info("Native feature management is not supported")

    return wrapper


async def is_native_feature_management_supported():
    """Whether we support native feature management on the panel."""

    hp = HostingPanel()
    if hp.NAME == cPanel.NAME:
        try:
            return Version(await hp.version()) >= Version("68.0")
        except ValueError:
            return False

    return False


@supported
async def is_native_feature_management_enabled():
    """Whether the native feature management is enabled."""

    hp = HostingPanel()
    return (
        hp.is_extension_installed(
            pkgs=NATIVE_FEATURE_MANAGEMENT_PACKAGE_EXTENSION_FILES
        )
        and await hp.is_hook_installed()
    )


@supported
async def enable_native_feature_management():
    """Enable native feature management."""

    hp = HostingPanel()

    # reset feature values for all existing users
    await reset_features(
        **{
            feature: EXTENSION_DEFAULTS[pe_var]
            for feature, pe_var in FEATURE_EXT_VARIABLES.items()
        }
    )

    await hp.install_extension(
        NATIVE_EXTENSION_NAME,
        NATIVE_FEATURE_MANAGEMENT_PACKAGE_EXTENSION_FILES,
        **EXTENSION_DEFAULTS,
    )

    logger.info("Imunify360 native feature management enabled.")


@supported
async def disable_native_feature_management():
    """Disable native feature management."""

    if not await is_native_feature_management_enabled():
        logger.info("No Imunify360 package extensions to disable.")
        return True

    await HostingPanel().uninstall_extension(
        NATIVE_EXTENSION_NAME,
        NATIVE_FEATURE_MANAGEMENT_PACKAGE_EXTENSION_FILES,
    )

    logger.info("Imunify360 native feature management disabled.")
    return True  # disabled successfully
