"""Manifest discovery and capability resolution."""

from __future__ import annotations

import importlib

from bridge_platform.apps.contracts import AppManifest


class AppContractError(ValueError):
    pass


def load_manifest(app_id: str) -> AppManifest | None:
    module = importlib.import_module(f"apps.{app_id}")
    manifest = getattr(module, "APP_MANIFEST", None)
    if manifest is None:
        return None
    if not isinstance(manifest, AppManifest):
        raise AppContractError(f"{app_id} APP_MANIFEST has an invalid type")
    errors = manifest.validate()
    if errors:
        raise AppContractError(f"{app_id} manifest invalid: {'; '.join(errors)}")
    if manifest.app_id != app_id:
        raise AppContractError(f"Manifest app_id does not match module: {app_id}")
    return manifest


def resolve_capability(caller_app: str, target_app: str, capability: str) -> str:
    caller = load_manifest(caller_app)
    target = load_manifest(target_app)
    if caller is None or target is None:
        raise AppContractError("Capability calls require standard v1 manifests on both apps")
    if not caller.allows_call(target_app, capability):
        raise PermissionError(
            f"{caller_app} is not allowed to call {target_app}:{capability}"
        )
    action = target.action_for_capability(capability)
    if action is None:
        raise LookupError(f"{target_app} does not export capability: {capability}")
    return action
