"""Compress tools — zip, tar, gzip, bz2, lzma compression and archives."""

from __future__ import annotations

import base64
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mcp.server.fastmcp import FastMCP


def _b64(data: bytes) -> str:
    return base64.b64encode(data).decode("ascii")


def _raw(b64: str) -> bytes:
    return base64.b64decode(b64)


def register(mcp: FastMCP) -> None:
    from peasy_compress import engine

    @mcp.tool()
    def compress_zip_create(files: dict[str, str], level: str = "default") -> str:
        """Create a ZIP archive from files.

        files: Dict of {filename: base64_content}.
        level: Compression level ('fastest', 'default', 'best').
        Returns: Base64-encoded ZIP archive.
        """
        raw_files = {name: _raw(content) for name, content in files.items()}
        return _b64(engine.zip_create(raw_files, level=level))  # type: ignore[arg-type]

    @mcp.tool()
    def compress_zip_extract(archive_b64: str) -> dict[str, str]:
        """Extract all files from a ZIP archive.

        archive_b64: Base64-encoded ZIP.
        Returns: Dict of {filename: base64_content}.
        """
        result = engine.zip_extract(_raw(archive_b64))
        return {name: _b64(data) for name, data in result.items()}

    @mcp.tool()
    def compress_zip_list(archive_b64: str) -> dict[str, object]:
        """List contents of a ZIP archive.

        Returns: Dict with total_files, total_size, compressed_size, entries.
        """
        info = engine.zip_list(_raw(archive_b64))
        return {
            "file_count": info.file_count,
            "total_size": info.total_size,
            "total_compressed": info.total_compressed,
            "entries": [
                {
                    "name": e.name,
                    "size": e.size,
                    "compressed_size": e.compressed_size,
                    "is_dir": e.is_dir,
                }
                for e in info.entries
            ],
        }

    @mcp.tool()
    def compress_gzip(data_b64: str, level: int = 9) -> str:
        """Compress data with gzip.

        Returns: Base64-encoded gzip data.
        """
        return _b64(engine.gzip_compress(_raw(data_b64), level=level))

    @mcp.tool()
    def compress_gunzip(data_b64: str) -> str:
        """Decompress gzip data.

        Returns: Base64-encoded decompressed data.
        """
        return _b64(engine.gzip_decompress(_raw(data_b64)))

    @mcp.tool()
    def compress_bz2(data_b64: str, level: int = 9) -> str:
        """Compress data with bzip2.

        Returns: Base64-encoded bz2 data.
        """
        return _b64(engine.bz2_compress(_raw(data_b64), level=level))

    @mcp.tool()
    def compress_bunzip2(data_b64: str) -> str:
        """Decompress bzip2 data.

        Returns: Base64-encoded decompressed data.
        """
        return _b64(engine.bz2_decompress(_raw(data_b64)))

    @mcp.tool()
    def compress_lzma(data_b64: str) -> str:
        """Compress data with LZMA/xz.

        Returns: Base64-encoded LZMA data.
        """
        return _b64(engine.lzma_compress(_raw(data_b64)))

    @mcp.tool()
    def compress_unlzma(data_b64: str) -> str:
        """Decompress LZMA/xz data.

        Returns: Base64-encoded decompressed data.
        """
        return _b64(engine.lzma_decompress(_raw(data_b64)))
