from __future__ import annotations
from typing import Protocol, runtime_checkable, Any, Iterable, Sequence
from zempy.zosapi.tools.general.protocols.quick_focus import IQuickFocus
from zempy.zosapi.tools.general.protocols.quick_adjust import QuickAdjustTool
from zempy.zosapi.tools.general.protocols.export_cad import ExportCADTool
from zempy.zosapi.tools.general.protocols.scale import ScaleTool
from zempy.zosapi.tools.general.protocols.archive import CreateArchiveTool, RestoreArchiveTool
from zempy.zosapi.tools.general.protocols.compute_rms_spot_size import ComputeRMSSpotSizeTool
from zempy.zosapi.tools.general.protocols.lens_catalogs import LensCatalogsTool

@runtime_checkable
class ISystemTools(Protocol):
    """   Python-facing contract for ZOSAPI.Tools.IOpticalSystemTools."""

    def open_quick_focus(self) -> IQuickFocus: ...
    def open_quick_adjust(self) -> QuickAdjustTool: ...
    def open_export_cad(self) -> ExportCADTool: ...
    def open_scale(self) -> ScaleTool: ...
    def open_create_zar(self) -> CreateArchiveTool: ...
    def open_restore_zar(self) -> RestoreArchiveTool: ...
    def open_rms_spot_radius_calculator(self) -> ComputeRMSSpotSizeTool: ...
    def open_lens_catalogs(self) -> LensCatalogsTool: ...

    # Ray tracing (TODO: replace Any with your specific Protocols when you define them)
    def open_batch_ray_trace(self) -> Any: ...
    def open_nsc_ray_trace(self) -> Any: ...
    def open_nsc_ray_trace_hpc(self, hpc_settings: Any) -> Any: ...
    def open_ray_database_reader(self) -> Any: ...

    # Optimization (TODO)
    def open_local_optimization(self) -> Any: ...
    def open_global_optimization(self) -> Any: ...
    def open_global_optimization_hpc(self, hpc_settings: Any) -> Any: ...
    def open_hammer_optimization(self) -> Any: ...
    def open_hammer_optimization_hpc(self, hpc_settings: Any) -> Any: ...
    def open_merit_function_calculator(self) -> Any: ...

    # Tolerancing (TODO)
    def open_tolerancing(self) -> Any: ...
    def open_tolerancing_hpc(self, hpc_settings: Any) -> Any: ...
    def open_tolerance_data_viewer(self) -> Any: ...
    def open_quick_sensitivity(self) -> Any: ...

    # Conversion / Design utilities (TODO)
    def open_convert_to_nsc_group(self) -> Any: ...
    def open_design_lockdown(self) -> Any: ...
    def open_critical_rayset_generator(self) -> Any: ...
    def open_find_best_asphere(self) -> Any: ...
    def open_convert_asphere_types(self) -> Any: ...
    def open_ray_aiming_wizard(self) -> Any: ...

    # HPC settings (TODO)
    def get_hpc_settings_from_prefs(self) -> Any: ...
    def get_hpc_settings_custom(self, node_count: int, instance_type: Any) -> Any: ...

    # Geometry/Point/Hull/Shaded model export (TODO)
    def get_point_tools(self) -> Any: ...
    def get_hull_tools(self) -> Any: ...
    def open_shaded_model_visualization_export(self) -> Any: ...

    # File operations / Projects (TODO)
    def open_file_manager(self) -> Any: ...
    def open_project_to_file_converter(self) -> Any: ...
    def open_restore_project(self) -> Any: ...
    def open_create_project(self) -> Any: ...
    def open_export_to_speos_lens_system(self) -> Any: ...
    def open_export_to_speos_whitebox(self) -> Any: ...

    # Misc utilities (TODO)
    def get_utilities(self) -> Any: ...
    def open_layouts(self) -> Any: ...  # if you expose Layouts as a tool

    # ----------------------------
    # System-wide helpers
    # ----------------------------

    def remove_all_variables(self) -> bool: ...
    def set_all_radii_variable(self) -> int: ...
    def set_all_thicknesses_variable(self) -> int: ...

    # SAFEARRAY helper allocations (you can return Python-native containers)
    def create_double_vector(self, num_elements: int) -> Sequence[float]: ...
    def create_double_matrix(self, rows: int, cols: int) -> Iterable[Iterable[float]]: ...

    # Unit conversion helpers
    def get_conversion_to_system_units(self, from_units: Any) -> float: ...
    def get_conversion_from_system_units(self, to_units: Any) -> float: ...

    # ----------------------------
    # Live status (pass-throughs to underlying tool runner)
    # ----------------------------

    @property
    def current_tool(self) -> Any:
        """The currently open tool (adapter) if any; else None."""
        ...

    @property
    def progress(self) -> int:
        """Progress (0–100) if available."""
        ...

    @property
    def status(self) -> str:
        """Status string if available."""
        ...

    @property
    def is_running(self) -> bool:
        """Whether a tool is currently running asynchronously."""
        ...

    @property
    def layouts(self) -> Any:
        """Layouts interface, if you expose it via tools."""
        ...

    @property
    def last_error(self) -> Any:
        """Last error message object from tools, if available."""
        ...
