import os
import sys
import platform
from abc import ABC, abstractmethod


class FlutNative(ABC):
    """Abstract base class for platform-specific FFI operations."""

    @staticmethod
    def _create() -> "FlutNative":
        """Create platform-specific FlutNative instance."""
        if os.name == "nt":
            from .windows import FlutWindowsNative
            return FlutWindowsNative()
        elif sys.platform == "darwin":
            from .macos import FlutMacOSNative
            return FlutMacOSNative()
        elif sys.platform.startswith("linux"):
            from .linux import FlutLinuxNative
            return FlutLinuxNative()
        else:
            raise NotImplementedError(f"Platform {sys.platform} not supported yet.")

    @staticmethod
    def _get_arch() -> str:
        """Return Flutter's architecture name for the current platform."""
        machine = platform.machine().lower()
        if machine in ("amd64", "x86_64", "x64"):
            return "x64"
        elif machine in ("arm64", "aarch64"):
            return "arm64"
        return "x64"  # fallback

    @abstractmethod
    def initialize(self):
        """Load native libraries."""
        pass

    @abstractmethod
    def run(self, method_call_handler, assets_path: str, width: int, height: int):
        """Run the Flutter engine with window and message loop.
        
        Args:
            method_call_handler: Callable that handles method calls from Dart.
            assets_path: Path to flutter_assets.
            width: Window width.
            height: Window height.
        """
        pass

    @abstractmethod
    def setup_call_dart(self, callback_addr):
        """Set up FFI callback for synchronous Python → Dart calls.
        
        Returns a callable: (call_type: str, data: dict) -> dict | None
        """
        pass

    @abstractmethod
    def setup_notify_dart(self, callback_addr):
        """Set up FFI callback for async notifications to Dart.
        
        Returns a callable: (data_bytes: bytes) -> None
        """
        pass

    @abstractmethod
    def shutdown(self):
        """Clean up native resources."""
        pass

    @staticmethod
    def get_default_assets_path() -> str:
        """Return the default path to flutter_assets for this platform."""
        raise NotImplementedError

