import logging from typing import Dict, List, Optional from .base import BaseVendor logger = logging.getLogger(__name__) class VendorRegistry: """ Central registry for verification vendors. Manages active vendor adapters and resolves waterfall order. """ def __init__(self): self._vendors: Dict[str, BaseVendor] = {} def register(self, vendor: BaseVendor, overwrite: bool = True) -> None: """Register a vendor instance.""" vendor_key = vendor.name.lower() if vendor_key in self._vendors and not overwrite: logger.warning("Vendor '%s' is already registered. Skipping.", vendor_key) return self._vendors[vendor_key] = vendor logger.info("Registered vendor '%s' (priority=%d, active=%s)", vendor.name, vendor.priority, vendor.is_active) def unregister(self, vendor_name: str) -> Optional[BaseVendor]: """Unregister a vendor instance.""" return self._vendors.pop(vendor_name.lower(), None) def get_vendor(self, vendor_name: str) -> Optional[BaseVendor]: """Retrieve vendor by name.""" return self._vendors.get(vendor_name.lower()) def get_all_vendors(self) -> List[BaseVendor]: """Return all registered vendors sorted by priority (lowest number = highest priority).""" return sorted(self._vendors.values(), key=lambda v: v.priority) def get_vendors_for_document( self, document_type: str, preferred_vendor: Optional[str] = None, ) -> List[BaseVendor]: """ Get all active vendors that support `document_type`, sorted by priority. If `preferred_vendor` is specified, it is placed at the front of the chain. """ doc_key = document_type.lower() active_candidates = [ v for v in self._vendors.values() if v.is_active and v.supports(doc_key) ] # Sort by priority active_candidates.sort(key=lambda v: v.priority) # If preferred vendor is requested and available, move it to index 0 if preferred_vendor: pref_key = preferred_vendor.lower() matching = [v for v in active_candidates if v.name.lower() == pref_key] if matching: remaining = [v for v in active_candidates if v.name.lower() != pref_key] return matching + remaining return active_candidates # Global default registry instance registry = VendorRegistry()