"""Post-processing pipeline for generated .pyi files.

Applies transformations like import normalization, trimming, and sorting.
"""

from __future__ import annotations

import ast
import logging
from pathlib import Path

from ..config import StubgenPyxConfig
from .collect_names import collect_names
from .normalize_names import normalize_names
from .sort_imports import sort_imports
from .epilog import epilog

logger = logging.getLogger(__name__)


def postprocessing_pipeline(
    pyi_code: str, config: StubgenPyxConfig, pyx_path: Path | None = None
) -> str:
    """Apply post-processing transformations to .pyi code.

    Optimizes by combining multiple AST passes where possible.

    Args:
        pyi_code: Generated .pyi code to postprocess.
        config: Configuration options for processing.
        pyx_path: Optional source file path for epilog comments.

    Returns:
        Processed .pyi code after all enabled transformations.
    """
    pyi_ast = ast.parse(pyi_code)

    if (
        not config.no_deduplicate_imports
        or not config.no_trim_imports
        or not config.no_normalize_names
    ):
        pyi_ast = _combined_import_transform(
            pyi_ast,
            trim_unused=not config.no_trim_imports,
            normalize=not config.no_normalize_names,
            deduplicate=not config.no_deduplicate_imports,
        )
    else:
        if not config.no_normalize_names:
            pyi_ast = normalize_names(pyi_ast)

    pyi_code = ast.unparse(pyi_ast)

    if not config.no_sort_imports:
        pyi_code = sort_imports(pyi_code)

    if not config.exclude_epilog:
        pyi_code = f"{pyi_code}\n\n{epilog(pyx_path)}"

    return pyi_code


def _combined_import_transform(
    tree: ast.AST,
    trim_unused: bool = True,
    normalize: bool = True,
    deduplicate: bool = True,
) -> ast.AST:
    """Combine import transformations into a single AST pass for efficiency."""
    from .normalize_names import _NameNormalizer
    from .trim_imports import _UnusedImportRemover
    from .deduplicate_imports import _DuplicateImportRemover

    if deduplicate:
        tree = _DuplicateImportRemover().visit(tree)

    if normalize:
        tree = _NameNormalizer().visit(tree)

    used_names = None
    if trim_unused:
        used_names = collect_names(tree)

    if trim_unused and used_names is not None:
        tree = _UnusedImportRemover(used_names).visit(tree)

    return tree
