"""Configuration deployment functionality for CLI config-deploy command.

Provides the business logic for deploying default configuration to application,
host, or user configuration locations. Uses lib_layered_config's deploy_config
function to copy the bundled defaultconfig.toml to requested target layers.

Contents:
    * :func:`deploy_configuration` – deploys configuration to specified targets

System Role:
    Lives in the behaviors layer. The CLI command delegates to this module for
    all configuration deployment logic, keeping the CLI layer focused on argument
    parsing and user interaction.
"""

from __future__ import annotations

from collections.abc import Sequence
from pathlib import Path

from lib_layered_config import deploy_config
from lib_layered_config.examples.deploy import DeployAction, DeployResult

from . import __init__conf__
from .config import get_default_config_path
from .enums import DeployTarget

_DEPLOYED_ACTIONS = frozenset({DeployAction.CREATED, DeployAction.OVERWRITTEN})


def _extract_deployed_paths(results: list[DeployResult]) -> list[Path]:
    """Extract destination paths from deploy results where files were actually deployed.

    Filters results to only include paths where files were created or overwritten,
    excluding skipped or kept files. Also recursively extracts paths from .d directory
    deployments.

    Args:
        results: List of DeployResult objects from deploy_config.

    Returns:
        List of Path objects for files that were created or overwritten.
    """
    paths: list[Path] = []
    for result in results:
        if result.action in _DEPLOYED_ACTIONS:
            paths.append(result.destination)
        for dot_d_result in result.dot_d_results:
            if dot_d_result.action in _DEPLOYED_ACTIONS:
                paths.append(dot_d_result.destination)
    return paths


def deploy_configuration(
    *,
    targets: Sequence[DeployTarget],
    force: bool = False,
    profile: str | None = None,
) -> list[Path]:
    r"""Deploy default configuration to specified target layers.

    Users need to initialize configuration files in standard locations
    (application, host, or user config directories) without manually
    copying files or knowing platform-specific paths. Uses
    lib_layered_config.deploy_config() to copy the bundled defaultconfig.toml
    to requested target layers (app, host, user).

    Args:
        targets: Sequence of DeployTarget enum values specifying target layers.
            Valid values: DeployTarget.APP, DeployTarget.HOST, DeployTarget.USER.
            Multiple targets can be specified to deploy to several locations at once.
        force: If True, overwrite existing configuration files. If False (default),
            skip files that already exist.
        profile: Optional profile name for environment isolation. When specified,
            configuration is deployed to profile-specific subdirectories
            (e.g., ~/.config/slug/profile/<name>/config.toml).

    Returns:
        List of paths where configuration files were created or would be created.
        Empty list if all target files already exist and force=False.

    Raises:
        PermissionError: When deploying to app/host without sufficient privileges.
        ValueError: When invalid target names are provided.

    Side Effects:
        Creates configuration files in platform-specific directories:
        - app: System-wide application config (requires privileges)
        - host: System-wide host config (requires privileges)
        - user: User-specific config (current user's home directory)

    Note:
        Platform-specific paths (without profile):
        - Linux (app): /etc/xdg/{slug}/config.toml
        - Linux (host): /etc/xdg/{slug}/config.toml
        - Linux (user): ~/.config/{slug}/config.toml
        - macOS (app): /Library/Application Support/{vendor}/{app}/config.toml
        - macOS (user): ~/Library/Application Support/{vendor}/{app}/config.toml
        - Windows (app): C:\ProgramData\{vendor}\{app}\config.toml
        - Windows (user): %APPDATA%\{vendor}\{app}\config.toml

        Platform-specific paths (with profile='production'):
        - Linux (user): ~/.config/{slug}/profile/production/config.toml
        - etc.

    Example:
        >>> paths = deploy_configuration(targets=[DeployTarget.USER])  # doctest: +SKIP
        >>> len(paths) > 0  # doctest: +SKIP
        True
        >>> paths[0].exists()  # doctest: +SKIP
        True

        >>> # Deploy to production profile
        >>> paths = deploy_configuration(  # doctest: +SKIP
        ...     targets=[DeployTarget.USER],
        ...     profile="production"
        ... )
    """
    source = get_default_config_path()

    # DeployTarget inherits from str, so enum members are already strings
    target_strings = list(targets)

    results = deploy_config(
        source=source,
        vendor=__init__conf__.LAYEREDCONF_VENDOR,
        app=__init__conf__.LAYEREDCONF_APP,
        slug=__init__conf__.LAYEREDCONF_SLUG,
        profile=profile,
        targets=target_strings,
        force=force,
    )

    return _extract_deployed_paths(results)


__all__ = [
    "deploy_configuration",
]
