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

import typing
import pathlib
from styxdefs import *

CIFTI_MERGE_METADATA = Metadata(
    id="7fb02481d87d8cd2e3909083db81c14bb985ba00.workbench",
    name="cifti-merge",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_CiftiMergeUpToParamsDictNoTag = typing.TypedDict('_CiftiMergeUpToParamsDictNoTag', {
    "last-index": str,
    "reverse": bool,
})
CiftiMergeUpToParamsDictTagged = typing.TypedDict('CiftiMergeUpToParamsDictTagged', {
    "@type": typing.Literal["up-to"],
    "last-index": str,
    "reverse": bool,
})
CiftiMergeUpToParamsDict = _CiftiMergeUpToParamsDictNoTag | CiftiMergeUpToParamsDictTagged


_CiftiMergeIndexParamsDictNoTag = typing.TypedDict('_CiftiMergeIndexParamsDictNoTag', {
    "index": str,
    "up-to": typing.NotRequired[CiftiMergeUpToParamsDict | None],
})
CiftiMergeIndexParamsDictTagged = typing.TypedDict('CiftiMergeIndexParamsDictTagged', {
    "@type": typing.Literal["index"],
    "index": str,
    "up-to": typing.NotRequired[CiftiMergeUpToParamsDict | None],
})
CiftiMergeIndexParamsDict = _CiftiMergeIndexParamsDictNoTag | CiftiMergeIndexParamsDictTagged


_CiftiMergeCiftiParamsDictNoTag = typing.TypedDict('_CiftiMergeCiftiParamsDictNoTag', {
    "cifti-in": InputPathType,
    "index": typing.NotRequired[list[CiftiMergeIndexParamsDict] | None],
})
CiftiMergeCiftiParamsDictTagged = typing.TypedDict('CiftiMergeCiftiParamsDictTagged', {
    "@type": typing.Literal["cifti"],
    "cifti-in": InputPathType,
    "index": typing.NotRequired[list[CiftiMergeIndexParamsDict] | None],
})
CiftiMergeCiftiParamsDict = _CiftiMergeCiftiParamsDictNoTag | CiftiMergeCiftiParamsDictTagged


_CiftiMergeParamsDictNoTag = typing.TypedDict('_CiftiMergeParamsDictNoTag', {
    "cifti-out": str,
    "cifti": typing.NotRequired[list[CiftiMergeCiftiParamsDict] | None],
    "limit-GB": typing.NotRequired[float | None],
    "direction": typing.NotRequired[str | None],
})
CiftiMergeParamsDictTagged = typing.TypedDict('CiftiMergeParamsDictTagged', {
    "@type": typing.Literal["workbench/cifti-merge"],
    "cifti-out": str,
    "cifti": typing.NotRequired[list[CiftiMergeCiftiParamsDict] | None],
    "limit-GB": typing.NotRequired[float | None],
    "direction": typing.NotRequired[str | None],
})
CiftiMergeParamsDict = _CiftiMergeParamsDictNoTag | CiftiMergeParamsDictTagged


def cifti_merge_up_to(
    last_index: str,
    reverse: bool = False,
) -> CiftiMergeUpToParamsDictTagged:
    """
    Build parameters.
    
    Args:
        last_index: the number or name of the last index to include.
        reverse: use the range in reverse order.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "up-to",
        "last-index": last_index,
        "reverse": reverse,
    }
    return params


def cifti_merge_up_to_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiMergeUpToParamsDict` 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("last-index", None) is None:
        raise StyxValidationError("`last-index` must not be None")
    if not isinstance(params["last-index"], str):
        raise StyxValidationError(f'`last-index` has the wrong type: Received `{type(params.get("last-index", None))}` expected `str`')
    if params.get("reverse", False) is None:
        raise StyxValidationError("`reverse` must not be None")
    if not isinstance(params["reverse"], bool):
        raise StyxValidationError(f'`reverse` has the wrong type: Received `{type(params.get("reverse", False))}` expected `bool`')


def cifti_merge_up_to_cargs(
    params: CiftiMergeUpToParamsDict,
    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([
        "-up-to",
        params.get("last-index", None)
    ])
    if params.get("reverse", False):
        cargs.append("-reverse")
    return cargs


def cifti_merge_index(
    index: str,
    up_to: CiftiMergeUpToParamsDict | None = None,
) -> CiftiMergeIndexParamsDictTagged:
    """
    Build parameters.
    
    Args:
        index: the index number (starting from 1), or name.
        up_to: use an inclusive range of indices.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "index",
        "index": index,
    }
    if up_to is not None:
        params["up-to"] = up_to
    return params


def cifti_merge_index_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiMergeIndexParamsDict` 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("index", None) is None:
        raise StyxValidationError("`index` must not be None")
    if not isinstance(params["index"], str):
        raise StyxValidationError(f'`index` has the wrong type: Received `{type(params.get("index", None))}` expected `str`')
    if params.get("up-to", None) is not None:
        cifti_merge_up_to_validate(params["up-to"])


def cifti_merge_index_cargs(
    params: CiftiMergeIndexParamsDict,
    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([
        "-index",
        params.get("index", None),
        *(cifti_merge_up_to_cargs(params.get("up-to", None), execution) if (params.get("up-to", None) is not None) else [])
    ])
    return cargs


def cifti_merge_cifti(
    cifti_in: InputPathType,
    index: list[CiftiMergeIndexParamsDict] | None = None,
) -> CiftiMergeCiftiParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cifti_in: a cifti file to use data from.
        index: select a single index to use.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "cifti",
        "cifti-in": cifti_in,
    }
    if index is not None:
        params["index"] = index
    return params


def cifti_merge_cifti_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiMergeCiftiParamsDict` 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("index", None) is not None:
        if not isinstance(params["index"], list):
            raise StyxValidationError(f'`index` has the wrong type: Received `{type(params.get("index", None))}` expected `list[CiftiMergeIndexParamsDict] | None`')
        for e in params["index"]:
            cifti_merge_index_validate(e)


def cifti_merge_cifti_cargs(
    params: CiftiMergeCiftiParamsDict,
    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([
        "-cifti",
        execution.input_file(params.get("cifti-in", None)),
        *([a for c in [cifti_merge_index_cargs(s, execution) for s in params.get("index", None)] for a in c] if (params.get("index", None) is not None) else [])
    ])
    return cargs


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


def cifti_merge_params(
    cifti_out: str,
    cifti: list[CiftiMergeCiftiParamsDict] | None = None,
    limit_gb: float | None = None,
    direction: str | None = None,
) -> CiftiMergeParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cifti_out: output cifti file.
        cifti: specify an input cifti file.
        limit_gb: restrict memory used for file reading efficiency\
            \
            memory limit in gigabytes.
        direction: merge in a direction other than along rows\
            \
            the dimension to split/concatenate along, default ROW.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/cifti-merge",
        "cifti-out": cifti_out,
    }
    if cifti is not None:
        params["cifti"] = cifti
    if limit_gb is not None:
        params["limit-GB"] = limit_gb
    if direction is not None:
        params["direction"] = direction
    return params


def cifti_merge_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiMergeParamsDict` 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-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("cifti", None) is not None:
        if not isinstance(params["cifti"], list):
            raise StyxValidationError(f'`cifti` has the wrong type: Received `{type(params.get("cifti", None))}` expected `list[CiftiMergeCiftiParamsDict] | None`')
        for e in params["cifti"]:
            cifti_merge_cifti_validate(e)
    if params.get("limit-GB", None) is not None:
        if not isinstance(params["limit-GB"], (float, int)):
            raise StyxValidationError(f'`limit-GB` has the wrong type: Received `{type(params.get("limit-GB", None))}` expected `float | None`')
    if params.get("direction", None) is not None:
        if not isinstance(params["direction"], str):
            raise StyxValidationError(f'`direction` has the wrong type: Received `{type(params.get("direction", None))}` expected `str | None`')


def cifti_merge_cargs(
    params: CiftiMergeParamsDict,
    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-merge"
    ])
    cargs.append(params.get("cifti-out", None))
    if params.get("cifti", None) is not None:
        cargs.extend([a for c in [cifti_merge_cifti_cargs(s, execution) for s in params.get("cifti", None)] for a in c])
    if params.get("limit-GB", None) is not None:
        cargs.extend([
            "-mem-limit",
            str(params.get("limit-GB", None))
        ])
    if params.get("direction", None) is not None:
        cargs.extend([
            "-direction",
            params.get("direction", None)
        ])
    return cargs


def cifti_merge_outputs(
    params: CiftiMergeParamsDict,
    execution: Execution,
) -> CiftiMergeOutputs:
    """
    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 = CiftiMergeOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(params.get("cifti-out", None)),
    )
    return ret


def cifti_merge_execute(
    params: CiftiMergeParamsDict,
    runner: Runner | None = None,
) -> CiftiMergeOutputs:
    """
    MERGE OR SPLIT ON SERIES, SCALAR, OR LABEL DIMENSIONS.
    
    Given input CIFTI files for which mappings along the selected direction are
    the same type, all either series, scalars, or labels, and the other
    dimensions are index-compatible, this command concatenates the data in the
    specified indices/ranges along the selected direction (by default, on
    typical 2D cifti, concatenate horizontally, so rows become longer). The
    direction can be either an integer starting from 1, or the strings 'ROW' or
    'COLUMN'.
    
    Example: wb_command -cifti-merge out.dtseries.nii -cifti first.dtseries.nii
    -index 1 -cifti second.dtseries.nii
    
    This example would take the first column from first.dtseries.nii, followed
    by all columns from second.dtseries.nii, and write these columns to
    out.dtseries.nii. .
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiMergeOutputs`).
    """
    cifti_merge_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_MERGE_METADATA)
    params = execution.params(params)
    cargs = cifti_merge_cargs(params, execution)
    ret = cifti_merge_outputs(params, execution)
    execution.run(cargs)
    return ret


def cifti_merge(
    cifti_out: str,
    cifti: list[CiftiMergeCiftiParamsDict] | None = None,
    limit_gb: float | None = None,
    direction: str | None = None,
    runner: Runner | None = None,
) -> CiftiMergeOutputs:
    """
    MERGE OR SPLIT ON SERIES, SCALAR, OR LABEL DIMENSIONS.
    
    Given input CIFTI files for which mappings along the selected direction are
    the same type, all either series, scalars, or labels, and the other
    dimensions are index-compatible, this command concatenates the data in the
    specified indices/ranges along the selected direction (by default, on
    typical 2D cifti, concatenate horizontally, so rows become longer). The
    direction can be either an integer starting from 1, or the strings 'ROW' or
    'COLUMN'.
    
    Example: wb_command -cifti-merge out.dtseries.nii -cifti first.dtseries.nii
    -index 1 -cifti second.dtseries.nii
    
    This example would take the first column from first.dtseries.nii, followed
    by all columns from second.dtseries.nii, and write these columns to
    out.dtseries.nii. .
    
    Args:
        cifti_out: output cifti file.
        cifti: specify an input cifti file.
        limit_gb: restrict memory used for file reading efficiency\
            \
            memory limit in gigabytes.
        direction: merge in a direction other than along rows\
            \
            the dimension to split/concatenate along, default ROW.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiMergeOutputs`).
    """
    params = cifti_merge_params(
        cifti_out=cifti_out,
        cifti=cifti,
        limit_gb=limit_gb,
        direction=direction,
    )
    return cifti_merge_execute(params, runner)


__all__ = [
    "CIFTI_MERGE_METADATA",
    "CiftiMergeCiftiParamsDict",
    "CiftiMergeCiftiParamsDictTagged",
    "CiftiMergeIndexParamsDict",
    "CiftiMergeIndexParamsDictTagged",
    "CiftiMergeOutputs",
    "CiftiMergeParamsDict",
    "CiftiMergeParamsDictTagged",
    "CiftiMergeUpToParamsDict",
    "CiftiMergeUpToParamsDictTagged",
    "cifti_merge",
    "cifti_merge_cifti",
    "cifti_merge_execute",
    "cifti_merge_index",
    "cifti_merge_params",
    "cifti_merge_up_to",
]
