# __init__.py - Package entry point

import os
import sys
import warnings

try:
    from ._version import __version__
except ImportError:
    try:
        from _version import __version__
    except ImportError:
        __version__ = "unknown"


# ============================================================
# Export top-level functions from audio_parser
# ============================================================

try:
    from .audio_parser import (
        batch_get_metadata,
        batch_get_duration,
        batch_get_metadata_by_type,
        get_audio_duration,
        get_audio_metadata,
    )
except ImportError:
    try:
        from audio_parser import (
            batch_get_metadata,
            batch_get_duration,
            batch_get_metadata_by_type,
            get_audio_duration,
            get_audio_metadata,
        )
    except ImportError:
        # Define as None if audio_parser not available
        batch_get_metadata = None
        batch_get_duration = None
        batch_get_metadata_by_type = None
        get_audio_duration = None
        get_audio_metadata = None

def is_full_performance() -> bool:
    """Check if running in full performance mode."""
    info = _auto_check_runtime()
    return info.get('is_full_performance', False) if info else False

def get_runtime_info() -> dict:
    """Get runtime information dictionary."""
    info = _auto_check_runtime()
    return info.copy() if info else {}
# ============================================================
# Banner
# ============================================================

if os.environ.get('AP_DS_HIDE_SUPPORT_PROMPT') != '1':
    print(f"AP_DS © - Audio Library By DVS  v{__version__} | https://apds.top")


# ============================================================
# Runtime Environment Detection
# ============================================================

SUPPRESS_WARNINGS = os.environ.get('AP_DS_SUPPRESS_WARNINGS', '').lower() in ('1', 'true', 'yes', 'on')
SHOW_CONGRATS = os.environ.get('AP_DS_SHOW_CONGRATS', '').lower() not in ('0', 'false', 'no', 'off')
_AUTO_CHECK_SKIP = os.environ.get('AP_DS_SKIP_AUTO_CHECK', '1').lower() in ('1', 'true', 'yes', 'on')
# ============================================================
# Show Technical Manual (User-Initiated)
# ============================================================

def show_tech_manual() -> None:
    """
    Display the complete AP_DS 4.0.0 Technical Manual.
    
    This function prints a comprehensive technical reference including:
        - Library architecture
        - Supported audio formats
        - Core components description
        - API reference
        - Performance tuning
        - Environment variables
        - Cross-platform notes
        - Troubleshooting guide
    
    User must call this function explicitly. It will NOT be called automatically.
    
    Examples:
        >>> from ap_ds import show_tech_manual
        >>> show_tech_manual()
    """
    manual = r"""
╔═══════════════════════════════════════════════════════════════════════════════╗
║                                                                               ║
║                     AP_DS 4.0.0 TECHNICAL MANUAL                              ║
║                  Audio Library By DVS - https://apds.top                      ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────────────────────────┐
│ 1. OVERVIEW                                                                  │
└───────────────────────────────────────────────────────────────────────────────┘

AP_DS (Audio Playback & Data Service) is a cross-platform, high-performance 
audio library for Python applications. Built on SDL2 and SDL2_mixer, it provides:

    • Low-latency audio playback
    • Accurate metadata parsing (pure Python, no external dependencies)
    • Smart WAV handling with automatic mode switching
    • DAP (Dvs Audio Playlist) recording with O(1) deduplication
    • Batch metadata extraction with multi-core parallelism
    • Fade in/out controls with position seeking
    • Memory-efficient caching with automatic cleanup

┌───────────────────────────────────────────────────────────────────────────────┐
│ 2. SUPPORTED AUDIO FORMATS                                                  │
└───────────────────────────────────────────────────────────────────────────────┘

    ┌──────────────┬─────────────┬─────────────────────────────────────────┐
    │ Format       │ Extension   │ Notes                                   │
    ├──────────────┼─────────────┼─────────────────────────────────────────┤
    │ MP3          │ .mp3        │ Frame-by-frame scanning, >98% accuracy  │
    │ WAV          │ .wav        │ RIFF chunk parsing, 100% accuracy       │
    │ FLAC         │ .flac       │ STREAMINFO block, 100% accuracy         │
    │ OGG Vorbis   │ .ogg        │ Granule position, 99.99% accuracy       │
    │ AAC (ADTS)   │ .aac        │ ADTS frame parsing, >99% accuracy       │
    └──────────────┴─────────────┴─────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────────────┐
│ 3. CORE COMPONENTS                                                           │
└───────────────────────────────────────────────────────────────────────────────┘

    3.1 AudioLibrary (player.py)
    ────────────────────────────
    Main class providing all audio playback and management functionality.
    
    Methods:
        • play_from_file(file_path, loops=0, start_pos=0.0) -> int
          Play audio directly from file, returns AID
        
        • play_from_memory(file_path, loops=0, start_pos=0.0) -> int
          Play audio from memory cache, returns AID
        
        • new_aid(file_path) -> int
          Generate AID without playing (preloads to cache)
        
        • pause_audio(aid) -> None
          Pause audio playback
        
        • stop_audio(aid) -> float
          Stop playback and return played duration
        
        • seek_audio(aid, position) -> None
          Seek to specified position in seconds
        
        • set_volume(aid, volume) -> bool
          Set volume (0-128)
        
        • get_volume(aid) -> int
          Get current volume
        
        • fadein_music(aid, loops=-1, ms=0) -> bool
          Fade in music
        
        • fadein_music_pos(aid, loops=-1, ms=0, position=0.0) -> bool
          Fade in music from position
        
        • fadeout_music(ms=0) -> bool
          Fade out music
        
        • clear_memory_cache() -> None
          Clear all cached audio data
        
        • save_dap_to_json(save_path) -> bool
          Save DAP recordings to .ap-ds-dap file
        
        • get_dap_recordings() -> List[Dict]
          Get current DAP recordings
        
        • clear_dap_recordings() -> None
          Clear all DAP recordings


    3.2 Metadata Parsers (audio_parser.py)
    ──────────────────────────────────────
    Pure-Python parsers for audio metadata extraction.
    
    Functions:
        • get_audio_duration(file_path) -> int
          Get duration in seconds
        
        • get_audio_metadata(file_path) -> Dict
          Get complete metadata (duration, sample_rate, channels, bitrate)
        
        • batch_get_metadata(file_paths, max_workers=None, show_progress=False) -> List[Dict]
          Parse multiple files in parallel
        
        • batch_get_duration(file_paths, max_workers=None) -> Dict[str, int]
          Get durations for multiple files
        
        • batch_get_metadata_by_type(file_paths, file_type, max_workers=None) -> List[Dict]
          Filter results by format


    3.3 SDL2 Loader (_sdl2.py)
    ──────────────────────────
    Cross-platform SDL2 library loader with automatic fallback.
    
    Loading order (Linux):
        1. Package directory
        2. User config (~/.config/ap_ds/sdl_paths.conf)
        3. System libraries
        4. Auto-install via package manager
        5. Interactive setup

    Loading order (Windows/macOS):
        1. Package directory
        2. System path
        3. Automatic download from CDN

┌───────────────────────────────────────────────────────────────────────────────┐
│ 4. DAP (Dvs Audio Playlist) SYSTEM                                          │
└───────────────────────────────────────────────────────────────────────────────┘

The DAP system automatically records every audio file that is played or loaded
through the AudioLibrary. Features:

    • O(1) Deduplication: Uses Python set for fast duplicate checking
    • Fallback O(n): Linear scan if set deduplication fails
    • Persistent Storage: Save to .ap-ds-dap JSON files
    • Memory Efficient: Stores only metadata, not audio data

Record Structure:
    {
        "path": "/path/to/audio.mp3",
        "duration": 240,
        "bitrate": 320000,
        "channels": 2
    }

┌───────────────────────────────────────────────────────────────────────────────┐
│ 5. WAV SMART MODE                                                           │
└───────────────────────────────────────────────────────────────────────────────┘

WAV files are automatically handled differently based on duration:

    ┌────────────────────┬─────────────────┬────────────────────────────────┐
    │ Duration           │ Mode            │ SDL2 API Used                 │
    ├────────────────────┼─────────────────┼────────────────────────────────┤
    │ < WAV_THRESHOLD    │ Sound Effect    │ Mix_PlayChannel (memory)      │
    │ >= WAV_THRESHOLD   │ Music           │ Mix_PlayMusic (streaming)     │
    └────────────────────┴─────────────────┴────────────────────────────────┘

Default threshold: 6 seconds
Configure via: AP_DS_WAV_THRESHOLD environment variable

┌───────────────────────────────────────────────────────────────────────────────┐
│ 6. ENVIRONMENT VARIABLES                                                     │
└───────────────────────────────────────────────────────────────────────────────┘

    AP_DS_WAV_THRESHOLD
        ─────────────────
        WAV mode switching threshold in seconds.
        Default: 6
        Range: 0-29 (values >=30 reset to 6)
        Example: AP_DS_WAV_THRESHOLD=10

    AP_DS_SUPPRESS_WARNINGS
        ─────────────────────
        Suppress GIL warning messages.
        Default: 0 (warnings enabled)
        Values: 1, true, yes, on
        Example: AP_DS_SUPPRESS_WARNINGS=1

    AP_DS_SHOW_CONGRATS
        ─────────────────
        Show congratulations message when GIL is disabled.
        Default: 1 (show)
        Values: 0, false, no, off (to hide)
        Example: AP_DS_SHOW_CONGRATS=0

    AP_DS_SKIP_AUTO_CHECK
        ───────────────────
        Skip runtime self-check on import.
        Default: 1 (skip)
        Values: 1, true, yes, on (to skip)
        Example: AP_DS_SKIP_AUTO_CHECK=0  # Show self-check

    AP_DS_HIDE_SUPPORT_PROMPT
        ──────────────────────
        Hide the support prompt banner.
        Default: 0 (show banner)
        Values: 1
        Example: AP_DS_HIDE_SUPPORT_PROMPT=1

┌───────────────────────────────────────────────────────────────────────────────┐
│ 7. PERFORMANCE OPTIMIZATION                                                 │
└───────────────────────────────────────────────────────────────────────────────┘

    7.1 Free-Threading Support
    ──────────────────────────
    AP_DS 4.0.0 is optimized for Python 3.15t (free-threading mode).
    When running with GIL disabled, performance improves significantly:
    
        • Batch metadata parsing uses ProcessPoolExecutor
        • Multiple audio operations can run in parallel
        • Lower latency for concurrent playback
    
    To enable free-threading:
        Download Python 3.15t from:
        https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip


    7.2 Batch Processing
    ────────────────────
    Use batch APIs for processing multiple files:
    
        metadata = batch_get_metadata(directory, max_workers=4, show_progress=True)
    
    Workers default to CPU count. Adjust based on:
        • I/O bound: Use more workers (CPU count * 2)
        • CPU bound: Use CPU count (or CPU count - 1 on 4+ cores)


    7.3 Memory Management
    ─────────────────────
    Audio data is cached in memory. To manage memory:
    
        • Use new_aid() to preload without playing
        • Call clear_memory_cache() periodically for long-running apps
        • WAV files under 6 seconds are cached as Mix_Chunk in memory
        • WAV files over 6 seconds stream via Mix_Music

┌───────────────────────────────────────────────────────────────────────────────┐
│ 8. CROSS-PLATFORM NOTES                                                     │
└───────────────────────────────────────────────────────────────────────────────┘

    8.1 Windows
    ───────────
        • DLLs automatically downloaded from CDN
        • SDL2.dll and SDL2_mixer.dll placed in package directory
        • os.add_dll_directory() used for modern Windows
        • PATH environment variable updated automatically

    8.2 macOS
    ─────────
        • Frameworks downloaded as DMG and auto-extracted
        • SDL2.framework and SDL2_mixer.framework
        • DYLD_FRAMEWORK_PATH updated automatically
        • Supports both Intel (x64) and Apple Silicon (ARM)

    8.3 Linux
    ─────────
        • No automatic download (distribution compatibility)
        • Uses system package manager when possible
        • Manual installation instructions provided
        • Supports: Ubuntu/Debian (apt), Fedora (dnf), Arch (pacman)
        • LD_LIBRARY_PATH updated when loading from package

┌───────────────────────────────────────────────────────────────────────────────┐
│ 9. TROUBLESHOOTING                                                          │
└───────────────────────────────────────────────────────────────────────────────┘

    9.1 "Failed to load music file"
    ──────────────────────────────
        • Verify file exists and is readable
        • Check if SDL2_mixer supports the format
        • For WAV files > 6s, ensure file is valid PCM

    9.2 "SDL initialization failed"
    ────────────────────────────────
        • SDL2 library not loaded properly
        • On Windows, check antivirus isn't blocking DLLs
        • On Linux, install SDL2 development packages

    9.3 "audio_parser not available"
    ──────────────────────────────────
        • audio_parser.py missing from package
        • Reinstall ap_ds: pip install --upgrade ap_ds

    9.4 "GIL is enabled" warning
    ──────────────────────────────
        • Running on standard Python (non-free-threading)
        • Upgrade to Python 3.15t for full performance
        • Or suppress with AP_DS_SUPPRESS_WARNINGS=1

    9.5 DAP recordings not saving
    ──────────────────────────────
        • Check file extension: must be .ap-ds-dap
        • Verify write permissions on save location
        • Ensure at least one file was played/loaded

┌───────────────────────────────────────────────────────────────────────────────┐
│ 10. API REFERENCE                                                           │
└───────────────────────────────────────────────────────────────────────────────┘

    10.1 AudioLibrary Class
    ───────────────────────
        class AudioLibrary(frequency=44100, format=MIX_DEFAULT_FORMAT,
                          channels=2, chunksize=2048)

        参数:
            frequency: Audio sample rate (Hz)
            format: Audio format (MIX_DEFAULT_FORMAT)
            channels: Number of channels (1=mono, 2=stereo)
            chunksize: Audio buffer size

    10.2 AID (Audio ID) System
    ──────────────────────────
        Every audio playback/load returns a unique AID.
        Use AID to control playback:
            aid = lib.play_from_file("song.mp3")
            lib.pause_audio(aid)
            lib.seek_audio(aid, 30.0)
            lib.stop_audio(aid)

    10.3 Channel vs Music
    ─────────────────────
        Sound Effect Mode (Mix_PlayChannel):
            • Up to 8 simultaneous sounds
            • Loaded into memory (Mix_Chunk)
            • Low latency
            • Best for short sounds (<6s)

        Music Mode (Mix_PlayMusic):
            • One at a time
            • Streamed from disk (Mix_Music)
            • Supports seeking and fading
            • Best for long tracks (>=6s)

┌───────────────────────────────────────────────────────────────────────────────┐
│ 11. VERSION HISTORY                                                         │
└───────────────────────────────────────────────────────────────────────────────┘

    Version 4.0.0 (Current)
    ────────────────────────
        • Python 3.15t free-threading support
        • Lazy imports for Python 3.15+
        • DAP O(1) deduplication
        • Batch metadata extraction
        • Smart WAV mode switching
        • Audio metadata parsers (pure Python)
        • Cross-platform SDL2 loader
    
    Version 3.x
    ───────────
        • Initial SDL2 bindings
        • Audio playback and control
        • Volume control
        • Basic metadata support

┌───────────────────────────────────────────────────────────────────────────────┐
│ 12. CONTRIBUTING & SUPPORT                                                  │
└───────────────────────────────────────────────────────────────────────────────┘

    Website: https://apds.top
    Source Code: https://gitcode.com/dvsxt/ap_ds
    Documentation: https://apds.top/docs
    Issues: https://gitcode.com/dvsxt/ap_ds/issues
    License: MIT

    Author: DVS
    Email: support@apds.top

╔═══════════════════════════════════════════════════════════════════════════════╗
║                           END OF MANUAL                                       ║
║                        AP_DS 4.0.0 - December 2025                           ║
║                                                                               ║
║    📖 For detailed Markdown documentation, visit:                            ║
║       https://apds.top                                                       ║
║       https://gitcode.com/dvsxt/ap_ds                                        ║
║                                                                               ║
║    📝 View source code:                                                      ║
║       https://gitcode.com/dvsxt/ap_ds                                        ║
║                                                                               ║
║    💬 Report issues:                                                         ║
║       https://gitcode.com/dvsxt/ap_ds/issues                                 ║
║                                                                               ║
║    💡 Quick start:                                                           ║
║       from ap_ds import AudioLibrary                                         ║
║       lib = AudioLibrary()                                                   ║
║       aid = lib.play_from_file("music.mp3")                                  ║
╚═══════════════════════════════════════════════════════════════════════════════╝
"""
    print(manual)
def _check_runtime_mode():
    """
    Check GIL status and notify the user accordingly.
    
    Returns:
        bool: True if GIL is enabled, False if disabled (free-threading)
    """
    try:
        gil_enabled = sys._is_gil_enabled()
    except AttributeError:
        gil_enabled = True

    if not gil_enabled:
        if SHOW_CONGRATS:
            print("🎉 ap_ds: GIL disabled (free-threading mode)")
    else:
        if not SUPPRESS_WARNINGS:
            warnings.warn(
                "⚠️ ap_ds: GIL is enabled (multi-core parallelism limited).\n"
                "   For full performance, upgrade to Python 3.15t:\n"
                "   https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip\n"
                "   To suppress this warning, set AP_DS_SUPPRESS_WARNINGS=1",
                RuntimeWarning,
                stacklevel=2
            )
    return gil_enabled
def _auto_check_runtime():
    """
    Automatic runtime self-check on library import.
    
    Prints diagnostic information including:
        - Python version
        - GIL status
        - Profiling availability
        - Performance mode
        - CPU cores
        - Platform
        - Library info (name, version, install path, website, author)
    
    Can be disabled by setting environment variable:
        AP_DS_SKIP_AUTO_CHECK=1
    
    Returns:
        dict: Runtime information dictionary
    """
    if _AUTO_CHECK_SKIP:
        return None

    print("\n" + "=" * 60)
    print("🔍 ap_ds Runtime Self-Check")
    print("=" * 60)

    # Library Info
    print(f"📚 Library: AP_DS (Audio Library By DVS)")
    print(f"📌 Version: {__version__}")
    print(f"📂 Install Path: {os.path.dirname(os.path.abspath(__file__))}")
    print(f"🌐 Website: https://apds.top")
    print(f"📦 PyPI: https://pypi.org/project/ap-ds/")
    print(f"📦 Mirror: https://pypi.tuna.tsinghua.edu.cn/simple/ap-ds/")
    print()
    print("📥 Installation:")
    print("   pip install ap-ds==4.0.0")
    print("   pip install ap-ds==4.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple")
    print("   pip install /path/to/ap-ds-4.0.0-py3-none-any.whl")
    print(f"👤 Author: DVS")
    print()
    print("📖 Description:")
    print("   AP_DS (Audio Playback & Data Service) is a cross-platform audio")
    print("   library built on SDL2 and SDL2_mixer, designed for Python applications")
    print("   requiring high-performance audio playback and metadata management.")
    print()
    print("   Core Features:")
    print("   • Audio Playback: MP3, WAV, FLAC, OGG, AAC, and more")
    print("   • Smart WAV Handling: Auto-switch between music/sound effect mode")
    print("   • Metadata Parsing: Duration, sample rate, channels, bitrate")
    print("   • DAP Recording: O(1) deduplication playlist generation")
    print("   • Batch Processing: Multi-core parallel metadata extraction")
    print("   • Fade Control: Fade in/out with position seeking support")
    print("   • Memory Management: Efficient caching with automatic cleanup")
    print()
    print("   Performance:")
    print("   • Native SDL2 bindings with zero-copy audio processing")
    print("   • Free-threading support (Python 3.15t) for maximum parallelism")
    print("   • ProcessPoolExecutor for CPU-bound batch operations")
    print()
    print("   Platform Support:")
    print("   • Windows (x64)  • macOS (x64/ARM)  • Linux (x64/ARM)")
    print()
    print("   Documentation: https://apds.top/docs")
    print("   Source Code: https://gitcode.com/dvsxt/ap_ds")
    print("   License: DVS Audio Library (ap_ds) Open Source License Version 2.0")
    print()
    print(f"🐍 Python: {sys.version.split()[0]} ({sys.implementation.name})")

    try:
        gil_enabled = sys._is_gil_enabled()
        print(f"🔒 GIL: {'Enabled' if gil_enabled else 'Disabled (Free-Threading)! 🎉'}")
    except AttributeError:
        gil_enabled = True
        print(f"🔒 GIL: Unknown (pre-3.14, assumed Enabled)")

    try:
        import profiling
        has_profiling = True
        print(f"📊 Profiling: Available (Python 3.15+)")
    except ImportError:
        has_profiling = False
        print(f"📊 Profiling: Not available (requires Python 3.15+)")

    is_full = has_profiling and not gil_enabled
    print(f"🚀 Full Performance Mode: {'✅ YES! (3.15t)' if is_full else '❌ No (degraded mode)'}")

    print(f"💻 CPU Cores: {os.cpu_count() or 0}")
    print(f"🖥️  Platform: {sys.platform}")
    print("=" * 60)

    if not is_full:
        print("💡 Tip: Upgrade to Python 3.15t for full performance:")
        print("   https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip")
        print("   To suppress this auto-check, set AP_DS_SKIP_AUTO_CHECK=1")
    else:
        print("🎉 You're running in full performance mode! Enjoy!")

    print("=" * 60 + "\n")
    
    return {
        "library_name": "AP_DS",
        "library_version": __version__,
        "library_install_path": os.path.dirname(os.path.abspath(__file__)),
        "library_website": "https://apds.top",
        "library_author": "DVS",
        "python_version": sys.version.split()[0],
        "gil_enabled": gil_enabled,
        "has_profiling": has_profiling,
        "is_full_performance": is_full,
        "cpu_count": os.cpu_count() or 0,
        "platform": sys.platform,
    }
# ============================================================
# Runtime Self-Check on Import
# ============================================================

_RUNTIME_CHECKED = False

def ensure_runtime_checked():
    """Ensure runtime check is performed only once."""
    global _RUNTIME_CHECKED
    if not _RUNTIME_CHECKED:
        _check_runtime_mode()
        _RUNTIME_CHECKED = True

ensure_runtime_checked()

# Execute auto self-check on import (user can call again later)
_auto_check_runtime()


# ============================================================
# Import Player Module (AudioLibrary and all core functions)
# ============================================================

try:
    from .player import *
except ImportError:
    from player import *

# ============================================================
# Export Self-Check Functions (users can call manually)
# ============================================================

try:
    # Try direct assignment first (functions already defined in this module)
    auto_check_runtime = _auto_check_runtime
    check_runtime_mode = _check_runtime_mode
except Exception:
    # Fallback: import from current package
    try:
        from . import _auto_check_runtime as auto_check_runtime
        from . import _check_runtime_mode as check_runtime_mode
    except Exception:
        # Final fallback: define as None
        auto_check_runtime = None
        check_runtime_mode = None

# ============================================================
# Public API
# ============================================================
# __init__.py 
__all__ = [
    "__version__",
    "AudioLibrary",
    "get_audio_duration",
    "get_audio_metadata",
    "batch_get_metadata",
    "batch_get_duration",
    "batch_get_metadata_by_type",
    "auto_check_runtime",
    "check_runtime_mode",
    "show_tech_manual",
]
