# This file was auto generated by Styx.
# Do not edit this file directly.

import typing
import pathlib
from styxdefs import *

CIFTI_ERODE_METADATA = Metadata(
    id="4f49d2de43c52dfd46795fc526b69cf0dadd9733.workbench",
    name="cifti-erode",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_CiftiErodeLeftSurfaceParamsDictNoTag = typing.TypedDict('_CiftiErodeLeftSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeLeftSurfaceParamsDictTagged = typing.TypedDict('CiftiErodeLeftSurfaceParamsDictTagged', {
    "@type": typing.Literal["left-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeLeftSurfaceParamsDict = _CiftiErodeLeftSurfaceParamsDictNoTag | CiftiErodeLeftSurfaceParamsDictTagged


_CiftiErodeRightSurfaceParamsDictNoTag = typing.TypedDict('_CiftiErodeRightSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeRightSurfaceParamsDictTagged = typing.TypedDict('CiftiErodeRightSurfaceParamsDictTagged', {
    "@type": typing.Literal["right-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeRightSurfaceParamsDict = _CiftiErodeRightSurfaceParamsDictNoTag | CiftiErodeRightSurfaceParamsDictTagged


_CiftiErodeCerebellumSurfaceParamsDictNoTag = typing.TypedDict('_CiftiErodeCerebellumSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeCerebellumSurfaceParamsDictTagged = typing.TypedDict('CiftiErodeCerebellumSurfaceParamsDictTagged', {
    "@type": typing.Literal["cerebellum-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiErodeCerebellumSurfaceParamsDict = _CiftiErodeCerebellumSurfaceParamsDictNoTag | CiftiErodeCerebellumSurfaceParamsDictTagged


_CiftiErodeParamsDictNoTag = typing.TypedDict('_CiftiErodeParamsDictNoTag', {
    "cifti-in": InputPathType,
    "direction": str,
    "surface-distance": float,
    "volume-distance": float,
    "cifti-out": str,
    "left-surface": typing.NotRequired[CiftiErodeLeftSurfaceParamsDict | None],
    "right-surface": typing.NotRequired[CiftiErodeRightSurfaceParamsDict | None],
    "cerebellum-surface": typing.NotRequired[CiftiErodeCerebellumSurfaceParamsDict | None],
    "merged-volume": bool,
})
CiftiErodeParamsDictTagged = typing.TypedDict('CiftiErodeParamsDictTagged', {
    "@type": typing.Literal["workbench/cifti-erode"],
    "cifti-in": InputPathType,
    "direction": str,
    "surface-distance": float,
    "volume-distance": float,
    "cifti-out": str,
    "left-surface": typing.NotRequired[CiftiErodeLeftSurfaceParamsDict | None],
    "right-surface": typing.NotRequired[CiftiErodeRightSurfaceParamsDict | None],
    "cerebellum-surface": typing.NotRequired[CiftiErodeCerebellumSurfaceParamsDict | None],
    "merged-volume": bool,
})
CiftiErodeParamsDict = _CiftiErodeParamsDictNoTag | CiftiErodeParamsDictTagged


def cifti_erode_left_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiErodeLeftSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the left surface file.
        area_metric: vertex areas to use instead of computing them from the\
            left surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "left-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


def cifti_erode_left_surface_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiErodeLeftSurfaceParamsDict` object.
    
    Args:
        params: The parameters object to validate.
    """
    if params is None or not isinstance(params, dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
    if params.get("surface", None) is None:
        raise StyxValidationError("`surface` must not be None")
    if not isinstance(params["surface"], (pathlib.Path, str)):
        raise StyxValidationError(f'`surface` has the wrong type: Received `{type(params.get("surface", None))}` expected `InputPathType`')
    if params.get("area-metric", None) is not None:
        if not isinstance(params["area-metric"], (pathlib.Path, str)):
            raise StyxValidationError(f'`area-metric` has the wrong type: Received `{type(params.get("area-metric", None))}` expected `InputPathType | None`')


def cifti_erode_left_surface_cargs(
    params: CiftiErodeLeftSurfaceParamsDict,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.extend([
        "-left-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-left-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


def cifti_erode_right_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiErodeRightSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the right surface file.
        area_metric: vertex areas to use instead of computing them from the\
            right surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "right-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


def cifti_erode_right_surface_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiErodeRightSurfaceParamsDict` object.
    
    Args:
        params: The parameters object to validate.
    """
    if params is None or not isinstance(params, dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
    if params.get("surface", None) is None:
        raise StyxValidationError("`surface` must not be None")
    if not isinstance(params["surface"], (pathlib.Path, str)):
        raise StyxValidationError(f'`surface` has the wrong type: Received `{type(params.get("surface", None))}` expected `InputPathType`')
    if params.get("area-metric", None) is not None:
        if not isinstance(params["area-metric"], (pathlib.Path, str)):
            raise StyxValidationError(f'`area-metric` has the wrong type: Received `{type(params.get("area-metric", None))}` expected `InputPathType | None`')


def cifti_erode_right_surface_cargs(
    params: CiftiErodeRightSurfaceParamsDict,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.extend([
        "-right-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-right-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


def cifti_erode_cerebellum_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiErodeCerebellumSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the cerebellum surface file.
        area_metric: vertex areas to use instead of computing them from the\
            cerebellum surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "cerebellum-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


def cifti_erode_cerebellum_surface_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiErodeCerebellumSurfaceParamsDict` object.
    
    Args:
        params: The parameters object to validate.
    """
    if params is None or not isinstance(params, dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
    if params.get("surface", None) is None:
        raise StyxValidationError("`surface` must not be None")
    if not isinstance(params["surface"], (pathlib.Path, str)):
        raise StyxValidationError(f'`surface` has the wrong type: Received `{type(params.get("surface", None))}` expected `InputPathType`')
    if params.get("area-metric", None) is not None:
        if not isinstance(params["area-metric"], (pathlib.Path, str)):
            raise StyxValidationError(f'`area-metric` has the wrong type: Received `{type(params.get("area-metric", None))}` expected `InputPathType | None`')


def cifti_erode_cerebellum_surface_cargs(
    params: CiftiErodeCerebellumSurfaceParamsDict,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.extend([
        "-cerebellum-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-cerebellum-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


class CiftiErodeOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiErodeParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    cifti_out: OutputPathType
    """the output cifti file"""


def cifti_erode_params(
    cifti_in: InputPathType,
    direction: str,
    surface_distance: float,
    volume_distance: float,
    cifti_out: str,
    left_surface: CiftiErodeLeftSurfaceParamsDict | None = None,
    right_surface: CiftiErodeRightSurfaceParamsDict | None = None,
    cerebellum_surface: CiftiErodeCerebellumSurfaceParamsDict | None = None,
    merged_volume: bool = False,
) -> CiftiErodeParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cifti_in: the input cifti file.
        direction: which dimension to dilate along, ROW or COLUMN.
        surface_distance: the distance to dilate on surfaces, in mm.
        volume_distance: the distance to dilate in the volume, in mm.
        cifti_out: the output cifti file.
        left_surface: specify the left surface to use.
        right_surface: specify the right surface to use.
        cerebellum_surface: specify the cerebellum surface to use.
        merged_volume: treat volume components as if they were a single\
            component.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/cifti-erode",
        "cifti-in": cifti_in,
        "direction": direction,
        "surface-distance": surface_distance,
        "volume-distance": volume_distance,
        "cifti-out": cifti_out,
        "merged-volume": merged_volume,
    }
    if left_surface is not None:
        params["left-surface"] = left_surface
    if right_surface is not None:
        params["right-surface"] = right_surface
    if cerebellum_surface is not None:
        params["cerebellum-surface"] = cerebellum_surface
    return params


def cifti_erode_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiErodeParamsDict` object.
    
    Args:
        params: The parameters object to validate.
    """
    if params is None or not isinstance(params, dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
    if params.get("cifti-in", None) is None:
        raise StyxValidationError("`cifti-in` must not be None")
    if not isinstance(params["cifti-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`cifti-in` has the wrong type: Received `{type(params.get("cifti-in", None))}` expected `InputPathType`')
    if params.get("direction", None) is None:
        raise StyxValidationError("`direction` must not be None")
    if not isinstance(params["direction"], str):
        raise StyxValidationError(f'`direction` has the wrong type: Received `{type(params.get("direction", None))}` expected `str`')
    if params.get("surface-distance", None) is None:
        raise StyxValidationError("`surface-distance` must not be None")
    if not isinstance(params["surface-distance"], (float, int)):
        raise StyxValidationError(f'`surface-distance` has the wrong type: Received `{type(params.get("surface-distance", None))}` expected `float`')
    if params.get("volume-distance", None) is None:
        raise StyxValidationError("`volume-distance` must not be None")
    if not isinstance(params["volume-distance"], (float, int)):
        raise StyxValidationError(f'`volume-distance` has the wrong type: Received `{type(params.get("volume-distance", None))}` expected `float`')
    if params.get("cifti-out", None) is None:
        raise StyxValidationError("`cifti-out` must not be None")
    if not isinstance(params["cifti-out"], str):
        raise StyxValidationError(f'`cifti-out` has the wrong type: Received `{type(params.get("cifti-out", None))}` expected `str`')
    if params.get("left-surface", None) is not None:
        cifti_erode_left_surface_validate(params["left-surface"])
    if params.get("right-surface", None) is not None:
        cifti_erode_right_surface_validate(params["right-surface"])
    if params.get("cerebellum-surface", None) is not None:
        cifti_erode_cerebellum_surface_validate(params["cerebellum-surface"])
    if params.get("merged-volume", False) is None:
        raise StyxValidationError("`merged-volume` must not be None")
    if not isinstance(params["merged-volume"], bool):
        raise StyxValidationError(f'`merged-volume` has the wrong type: Received `{type(params.get("merged-volume", False))}` expected `bool`')


def cifti_erode_cargs(
    params: CiftiErodeParamsDict,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.extend([
        "wb_command",
        "-cifti-erode"
    ])
    cargs.append(execution.input_file(params.get("cifti-in", None)))
    cargs.append(params.get("direction", None))
    cargs.append(str(params.get("surface-distance", None)))
    cargs.append(str(params.get("volume-distance", None)))
    cargs.append(params.get("cifti-out", None))
    if params.get("left-surface", None) is not None or params.get("right-surface", None) is not None or params.get("cerebellum-surface", None) is not None:
        cargs.extend([
            *(cifti_erode_left_surface_cargs(params.get("left-surface", None), execution) if (params.get("left-surface", None) is not None) else []),
            *(cifti_erode_right_surface_cargs(params.get("right-surface", None), execution) if (params.get("right-surface", None) is not None) else []),
            *(cifti_erode_cerebellum_surface_cargs(params.get("cerebellum-surface", None), execution) if (params.get("cerebellum-surface", None) is not None) else [])
        ])
    if params.get("merged-volume", False):
        cargs.append("-merged-volume")
    return cargs


def cifti_erode_outputs(
    params: CiftiErodeParamsDict,
    execution: Execution,
) -> CiftiErodeOutputs:
    """
    Build outputs object containing output file paths and possibly stdout/stderr.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Outputs object.
    """
    ret = CiftiErodeOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(params.get("cifti-out", None)),
    )
    return ret


def cifti_erode_execute(
    params: CiftiErodeParamsDict,
    runner: Runner | None = None,
) -> CiftiErodeOutputs:
    """
    ERODE A CIFTI FILE.
    
    For all data values that are empty (for label data, unlabeled, for other
    data, zero), set the surrounding values to empty. The surrounding values are
    defined as the immediate neighbors and all values in the same structure
    within the specified distance (-merged-volume treats all voxels as one
    structure).
    
    The -*-corrected-areas options are intended for eroding on group average
    surfaces, but it is only an approximate correction.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiErodeOutputs`).
    """
    cifti_erode_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_ERODE_METADATA)
    params = execution.params(params)
    cargs = cifti_erode_cargs(params, execution)
    ret = cifti_erode_outputs(params, execution)
    execution.run(cargs)
    return ret


def cifti_erode(
    cifti_in: InputPathType,
    direction: str,
    surface_distance: float,
    volume_distance: float,
    cifti_out: str,
    left_surface: CiftiErodeLeftSurfaceParamsDict | None = None,
    right_surface: CiftiErodeRightSurfaceParamsDict | None = None,
    cerebellum_surface: CiftiErodeCerebellumSurfaceParamsDict | None = None,
    merged_volume: bool = False,
    runner: Runner | None = None,
) -> CiftiErodeOutputs:
    """
    ERODE A CIFTI FILE.
    
    For all data values that are empty (for label data, unlabeled, for other
    data, zero), set the surrounding values to empty. The surrounding values are
    defined as the immediate neighbors and all values in the same structure
    within the specified distance (-merged-volume treats all voxels as one
    structure).
    
    The -*-corrected-areas options are intended for eroding on group average
    surfaces, but it is only an approximate correction.
    
    Args:
        cifti_in: the input cifti file.
        direction: which dimension to dilate along, ROW or COLUMN.
        surface_distance: the distance to dilate on surfaces, in mm.
        volume_distance: the distance to dilate in the volume, in mm.
        cifti_out: the output cifti file.
        left_surface: specify the left surface to use.
        right_surface: specify the right surface to use.
        cerebellum_surface: specify the cerebellum surface to use.
        merged_volume: treat volume components as if they were a single\
            component.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiErodeOutputs`).
    """
    params = cifti_erode_params(
        cifti_in=cifti_in,
        direction=direction,
        surface_distance=surface_distance,
        volume_distance=volume_distance,
        cifti_out=cifti_out,
        left_surface=left_surface,
        right_surface=right_surface,
        cerebellum_surface=cerebellum_surface,
        merged_volume=merged_volume,
    )
    return cifti_erode_execute(params, runner)


__all__ = [
    "CIFTI_ERODE_METADATA",
    "CiftiErodeCerebellumSurfaceParamsDict",
    "CiftiErodeCerebellumSurfaceParamsDictTagged",
    "CiftiErodeLeftSurfaceParamsDict",
    "CiftiErodeLeftSurfaceParamsDictTagged",
    "CiftiErodeOutputs",
    "CiftiErodeParamsDict",
    "CiftiErodeParamsDictTagged",
    "CiftiErodeRightSurfaceParamsDict",
    "CiftiErodeRightSurfaceParamsDictTagged",
    "cifti_erode",
    "cifti_erode_cerebellum_surface",
    "cifti_erode_execute",
    "cifti_erode_left_surface",
    "cifti_erode_params",
    "cifti_erode_right_surface",
]
