# This file is part of Gajim.
#
# SPDX-License-Identifier: GPL-3.0-only

import functools
import importlib.metadata
import os
import platform
import sys

from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Soup
from packaging.requirements import Requirement
from packaging.specifiers import SpecifierSet

CURRENT_PYTHON_VERSION = platform.python_version()


def python_version(specifier_set: str) -> bool:
    spec = SpecifierSet(specifier_set)
    return CURRENT_PYTHON_VERSION in spec


def package_version(requirement: str) -> bool:
    req = Requirement(requirement)
    try:
        installed_version = importlib.metadata.version(req.name)
    except importlib.metadata.PackageNotFoundError:
        return False

    return req.specifier.contains(installed_version, prereleases=True)


def gi_package_version(requirement: str):
    req = Requirement(requirement)
    match req.name:
        case "GLib":
            version = get_glib_version()
        case "PyGObject":
            version = get_gobject_version()
        case "Soup":
            version = get_soup_version()
        case _:
            raise ValueError("Unknown lib name: %s" % req.name)

    return req.specifier.contains(version)


@functools.lru_cache(maxsize=1)
def get_os_info() -> str:
    info = "N/A"
    if sys.platform in ("win32", "darwin"):
        info = f"{platform.system()} {platform.release()}"

    elif sys.platform == "linux":
        try:
            import distro

            info = distro.name(pretty=True)
        except ImportError:
            info = platform.system()
    return info


def get_os_name() -> str:
    if sys.platform in ("win32", "darwin"):
        return platform.system()
    if os.name == "posix":
        try:
            import distro

            return distro.name(pretty=True)
        except ImportError:
            return platform.system()
    return ""


def get_os_version() -> str:
    if sys.platform in ("win32", "darwin"):
        return platform.version()
    if os.name == "posix":
        try:
            import distro

            return distro.version(pretty=True)
        except ImportError:
            return platform.release()
    return ""


def get_gobject_version() -> str:
    return ".".join(map(str, GObject.pygobject_version))  # pyright: ignore


def get_glib_version() -> str:
    return ".".join(
        map(str, [GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION])
    )


def get_soup_version() -> str:
    return ".".join(
        map(
            str,
            [
                Soup.get_major_version(),
                Soup.get_minor_version(),
                Soup.get_micro_version(),
            ],
        )
    )
