"""获取当前工作空间环境的基本信息"""

import platform
import subprocess
import sys

from .time import now


def check_module_version(module_name: str, requirement: str) -> bool:
    """
    检查已安装模块的版本是否满足给定的 requirement

    Parameters
    ----------
      - module_name: 模块名称（如 "requests"）
      - requirement: 版本要求（如 ">=2.20,<3.0"）

    Returns
    ----------
      - True: 满足要求
      - False: 不满足要求
    """
    import warnings
    from importlib.metadata import PackageNotFoundError, version

    from packaging.specifiers import SpecifierSet

    try:
        installed_ver = version(module_name)
    except PackageNotFoundError:
        # raise ModuleNotFoundError(f"模块 '{module_name}' 未安装。")
        warnings.warn(f"模块 '{module_name}' 未安装")
        return False

    spec = SpecifierSet(requirement)
    return installed_ver in spec


def check_module_installed(module_name: str) -> bool:
    """
    检查是否已安装指定模块

    Parameters
    ----------
      - module_name: 模块名称（如 "requests"）

    Returns
    ----------
      - True: 已安装
      - False: 未安装
    """
    import importlib

    try:
        importlib.import_module(module_name)
        return True
    except ModuleNotFoundError:
        return False


def get_module_version(module_name: str) -> str:
    """
    获取指定模块的版本号

    Parameters
    ----------
      - module_name: 模块名称（如 "requests"）

    Returns
    ----------
      - 版本号
    """
    from importlib import metadata

    return metadata.version(module_name)


def get_system_fingerprint():
    import hashlib
    import uuid

    # 收集多种系统信息
    info = [
        platform.system(),  # 操作系统类型 (如: 'Windows', 'Linux', 'Darwin')
        # platform.node(),          # 主机名
        platform.machine(),  # 机器类型 (如: 'x86_64')
        platform.processor(),  # CPU 信息
        hex(uuid.getnode()),  # 唯一标识符
    ]
    # 生成哈希作为唯一ID
    fingerprint = hashlib.md5(str(info).encode()).hexdigest()
    return fingerprint


def env_status() -> dict[str, str]:
    platform_info = {
        'os': platform.system(),
        'os_ver': platform.version(),
        'machine': platform.machine(),
        'python': {'version': platform.python_version(), 'path': sys.executable},
        'now': now(),
    }

    # check if inside git repo
    if _check_git_repo():
        platform_info['git'] = {
            'branch': _git_current_branch(),
            'commit': _git_latest_commit(),
            'status': _git_porcelain(),
        }
    else:
        platform_info['git'] = 'Not git repo'

    platform_info['zyplib'] = get_module_version('zyplib')
    if check_module_installed('torch'):
        platform_info['torch'] = get_module_version('torch')

    return platform_info


def _check_git_repo() -> bool:
    """检查当前工作目录是否是一个 git 仓库"""
    try:
        # 使用 git rev-parse --is-inside-work-tree 来判断是否在 git 仓库中
        result = subprocess.run(
            ['git', 'rev-parse', '--is-inside-work-tree'],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            text=True,
            check=True,
        )
        return result.stdout.strip() == 'true'
    except (subprocess.CalledProcessError, FileNotFoundError):
        # 如果命令执行失败或 git 不存在, 则认为不在 git 仓库中
        return False


def _git_porcelain() -> str:
    """当前工作目录的 git 状态, 返回 git status --porcelain 的输出"""
    try:
        # 执行 git status --porcelain 命令, 如果输出为空, 则说明没有未提交的更改
        result = subprocess.run(
            ['git', 'status', '--porcelain'], capture_output=True, text=True, check=True
        )
        return result.stdout.strip()
    except subprocess.CalledProcessError:
        # 如果命令执行失败, 假设工作目录不是干净的
        return ''


def _git_latest_commit() -> str:
    """当前工作状态下，最近一次 git commit 的 hash

    如果当前 git 目录已经 commit，则返回 commit 的 id
    如果有暂存，则返回最近的一次的 commit 的 id
    """
    try:
        # 执行 git rev-parse HEAD 命令获取最近一次commit的hash
        result = subprocess.run(
            ['git', 'rev-parse', 'HEAD'], capture_output=True, text=True, check=True
        )
        # 返回去除空白的hash值
        return result.stdout.strip()
    except subprocess.CalledProcessError:
        # 如果命令执行失败,返回空字符串
        return ''


def _git_current_branch() -> str:
    """获取当前所在的 git branch 名称

    如果不在任何分支上(detached HEAD)，则返回空字符串
    """
    try:
        result = subprocess.run(
            ['git', 'branch', '--show-current'],
            capture_output=True,
            text=True,
            check=True,
        )
        return result.stdout.strip()
    except subprocess.CalledProcessError:
        return ''
