from collections.abc import Callable, Mapping
from typing import Literal, Union

from debputy.dh_migration.dh_related_migrations import (
    dh_mbm_migrate_package_files,
    dh_mbm_migrate_manual_warnings,
)
from debputy.dh_migration.migrators_impl import (
    migrate_links_files,
    migrate_maintscript,
    migrate_tmpfile,
    migrate_install_file,
    migrate_installdocs_file,
    migrate_installexamples_file,
    migrate_dh_hook_targets,
    migrate_misspelled_readme_debian_files,
    migrate_doc_base_files,
    migrate_lintian_overrides_files,
    detect_unsupported_zz_debputy_features,
    detect_pam_files,
    detect_modprobe_files,
    detect_dh_addons_with_zz_integration,
    migrate_not_installed_file,
    migrate_installman_file,
    migrate_bash_completion,
    migrate_installinfo_file,
    migrate_dh_installsystemd_files,
    detect_obsolete_substvars,
    detect_dh_addons_zz_debputy_rrr,
    detect_dh_addons_with_full_integration,
    migrate_shell_completions,
    migrate_clean_file,
    min_dh_compat_check,
    migrate_dh_builtusing,
)
from debputy.dh_migration.models import (
    FeatureMigration,
    MigrationRequest,
)
from debputy.plugin.api.spec import (
    DebputyIntegrationMode,
    INTEGRATION_MODE_DH_DEBPUTY_RRR,
    INTEGRATION_MODE_DH_DEBPUTY,
    INTEGRATION_MODE_FULL,
)

Migrator = Callable[
    [
        MigrationRequest,
        FeatureMigration,
    ],
    None,
]

_DH_DEBPUTY_MIGRATORS = [
    detect_unsupported_zz_debputy_features,
    detect_pam_files,
    detect_modprobe_files,
    migrate_dh_hook_targets,
    migrate_dh_installsystemd_files,
    migrate_install_file,
    migrate_installdocs_file,
    migrate_installexamples_file,
    migrate_installman_file,
    migrate_installinfo_file,
    migrate_misspelled_readme_debian_files,
    migrate_doc_base_files,
    migrate_links_files,
    migrate_maintscript,
    migrate_tmpfile,
    migrate_lintian_overrides_files,
    migrate_bash_completion,
    migrate_shell_completions,
    migrate_dh_builtusing,
    detect_obsolete_substvars,
    # not-installed should go last, so its rules appear after other installations
    # It is not perfect, but it is a start.
    migrate_not_installed_file,
    min_dh_compat_check,
]


MigrationTarget = Union[
    DebputyIntegrationMode,
    Literal[
        "dh-single-to-multi-binary",
        "dh-package-prefixed-config-files",
    ],
]

MIGRATORS: Mapping[MigrationTarget, list[Migrator]] = {
    INTEGRATION_MODE_DH_DEBPUTY_RRR: [
        migrate_dh_hook_targets,
        migrate_misspelled_readme_debian_files,
        detect_dh_addons_zz_debputy_rrr,
        detect_obsolete_substvars,
    ],
    INTEGRATION_MODE_DH_DEBPUTY: [
        *_DH_DEBPUTY_MIGRATORS,
        detect_dh_addons_with_zz_integration,
    ],
    INTEGRATION_MODE_FULL: [
        *_DH_DEBPUTY_MIGRATORS,
        detect_dh_addons_with_full_integration,
        migrate_clean_file,
    ],
    "dh-package-prefixed-config-files": [
        dh_mbm_migrate_package_files,
    ],
    "dh-single-to-multi-binary": [
        dh_mbm_migrate_package_files,
        dh_mbm_migrate_manual_warnings,
    ],
}
del _DH_DEBPUTY_MIGRATORS
