"""RadiensCore RPC wrappers — thin service layer (proto only)."""

from __future__ import annotations

from typing import TYPE_CHECKING

import grpc

from radiens_core._converters._enums import file_type_to_proto
from radiens_core._generated import datasource_pb2, radiensserver_pb2_grpc
from radiens_core._transport._errors import handle_grpc_error
from radiens_core.models.enums import ClientType, RadiensFileType

if TYPE_CHECKING:
    from radiens_core._transport._channel_pool import ChannelPool
    from radiens_core.models.dataset import DatasetMetadata


def _guess_file_type(path: str) -> RadiensFileType:
    """Guess file type from file extension."""
    ext = path.rsplit(".", maxsplit=1)[-1].lower() if "." in path else ""
    ext_map: dict[str, RadiensFileType] = {
        "xdat": RadiensFileType.XDAT,
        "rhd": RadiensFileType.RHD,
        "csv": RadiensFileType.CSV,
        "hdf5": RadiensFileType.HDF5,
        "h5": RadiensFileType.HDF5,
        "nex5": RadiensFileType.NEX5,
        "nwb": RadiensFileType.NWB,
        "bin": RadiensFileType.KILOSORT2,
        "nsx": RadiensFileType.NSX,
        "tdt": RadiensFileType.TDT,
        "oebin": RadiensFileType.OE_DAT,
    }
    return ext_map.get(ext, RadiensFileType.XDAT)


def set_datasource(
    pool: ChannelPool,
    addr: str,
    path: str,
) -> DatasetMetadata:
    """Link a data file via SetDataSourceFromFile RPC.

    Returns domain DatasetMetadata.
    """
    import os

    from radiens_core._converters._dataset import dataset_metadata_from_proto

    base_name = os.path.splitext(os.path.basename(path))[0]
    dir_path = os.path.dirname(path) or "."

    req = datasource_pb2.DataSourceSetSaveRequest(
        path=dir_path,
        baseName=base_name,
        fileType=file_type_to_proto(_guess_file_type(path)),
    )

    channel = pool.get_channel(addr)
    stub = radiensserver_pb2_grpc.RadiensCoreStub(channel)
    try:
        res = stub.SetDataSourceFromFile(req)
    except grpc.RpcError as ex:
        handle_grpc_error(ex, ClientType.VIDERE)
        raise  # unreachable, but satisfies mypy

    return dataset_metadata_from_proto(res)
