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

import typing
import pathlib
from styxdefs import *

TRANSFORMCOMPOSE_METADATA = Metadata(
    id="00dff5d1cb74f969e2ad40f5dbeaedf75a029491.boutiques",
    name="transformcompose",
    package="mrtrix",
    container_image_tag="mrtrix3/mrtrix3:3.0.4",
)


_TransformcomposeConfigParamsDictNoTag = typing.TypedDict('_TransformcomposeConfigParamsDictNoTag', {
    "key": str,
    "value": str,
})
TransformcomposeConfigParamsDictTagged = typing.TypedDict('TransformcomposeConfigParamsDictTagged', {
    "@type": typing.Literal["config"],
    "key": str,
    "value": str,
})
TransformcomposeConfigParamsDict = _TransformcomposeConfigParamsDictNoTag | TransformcomposeConfigParamsDictTagged


_TransformcomposeVariousStringParamsDictNoTag = typing.TypedDict('_TransformcomposeVariousStringParamsDictNoTag', {
    "obj": str,
})
TransformcomposeVariousStringParamsDictTagged = typing.TypedDict('TransformcomposeVariousStringParamsDictTagged', {
    "@type": typing.Literal["VariousString"],
    "obj": str,
})
TransformcomposeVariousStringParamsDict = _TransformcomposeVariousStringParamsDictNoTag | TransformcomposeVariousStringParamsDictTagged


_TransformcomposeVariousFileParamsDictNoTag = typing.TypedDict('_TransformcomposeVariousFileParamsDictNoTag', {
    "obj": InputPathType,
})
TransformcomposeVariousFileParamsDictTagged = typing.TypedDict('TransformcomposeVariousFileParamsDictTagged', {
    "@type": typing.Literal["VariousFile"],
    "obj": InputPathType,
})
TransformcomposeVariousFileParamsDict = _TransformcomposeVariousFileParamsDictNoTag | TransformcomposeVariousFileParamsDictTagged


_TransformcomposeParamsDictNoTag = typing.TypedDict('_TransformcomposeParamsDictNoTag', {
    "template": typing.NotRequired[InputPathType | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[TransformcomposeConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "input": list[InputPathType],
    "output": typing.Union[TransformcomposeVariousStringParamsDictTagged, TransformcomposeVariousFileParamsDictTagged],
})
TransformcomposeParamsDictTagged = typing.TypedDict('TransformcomposeParamsDictTagged', {
    "@type": typing.Literal["mrtrix/transformcompose"],
    "template": typing.NotRequired[InputPathType | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[TransformcomposeConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "input": list[InputPathType],
    "output": typing.Union[TransformcomposeVariousStringParamsDictTagged, TransformcomposeVariousFileParamsDictTagged],
})
TransformcomposeParamsDict = _TransformcomposeParamsDictNoTag | TransformcomposeParamsDictTagged


def transformcompose_output_cargs_dyn_fn(
    t: str,
) -> typing.Any:
    """
    Get build cargs function by command type.
    
    Args:
        t: Command type.
    Returns:
        Build cargs function.
    """
    return {
        "VariousString": transformcompose_various_string_cargs,
        "VariousFile": transformcompose_various_file_cargs,
    }.get(t)


def transformcompose_output_validate_dyn_fn(
    t: str,
) -> typing.Any:
    """
    Get validate params function by command type.
    
    Args:
        t: Command type.
    Returns:
        Validate params function.
    """
    return {
        "VariousString": transformcompose_various_string_validate,
        "VariousFile": transformcompose_various_file_validate,
    }.get(t)


def transformcompose_config(
    key: str,
    value: str,
) -> TransformcomposeConfigParamsDictTagged:
    """
    Build parameters.
    
    Args:
        key: temporarily set the value of an MRtrix config file entry.
        value: temporarily set the value of an MRtrix config file entry.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "config",
        "key": key,
        "value": value,
    }
    return params


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


def transformcompose_config_cargs(
    params: TransformcomposeConfigParamsDict,
    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.append("-config")
    cargs.append(params.get("key", None))
    cargs.append(params.get("value", None))
    return cargs


def transformcompose_various_string(
    obj: str,
) -> TransformcomposeVariousStringParamsDictTagged:
    """
    Build parameters.
    
    Args:
        obj: String object.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "VariousString",
        "obj": obj,
    }
    return params


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


def transformcompose_various_string_cargs(
    params: TransformcomposeVariousStringParamsDict,
    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.append(params.get("obj", None))
    return cargs


def transformcompose_various_file(
    obj: InputPathType,
) -> TransformcomposeVariousFileParamsDictTagged:
    """
    Build parameters.
    
    Args:
        obj: File object.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "VariousFile",
        "obj": obj,
    }
    return params


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


def transformcompose_various_file_cargs(
    params: TransformcomposeVariousFileParamsDict,
    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.append(execution.input_file(params.get("obj", None)))
    return cargs


class TransformcomposeOutputs(typing.NamedTuple):
    """
    Output object returned when calling `TransformcomposeParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""


def transformcompose_params(
    input_: list[InputPathType],
    output: typing.Union[TransformcomposeVariousStringParamsDictTagged, TransformcomposeVariousFileParamsDictTagged],
    template: InputPathType | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[TransformcomposeConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
) -> TransformcomposeParamsDictTagged:
    """
    Build parameters.
    
    Args:
        input_: the input transforms (either linear or non-linear warps).
        output: the output file (may be a linear transformation text file, or a\
            deformation warp field image, depending on usage).
        template: define the output grid defined by a template image.
        info: display information messages.
        quiet: do not display information messages or progress status;\
            alternatively, this can be achieved by setting the MRTRIX_QUIET\
            environment variable to a non-empty string.
        debug: display debugging messages.
        force: force overwrite of output files (caution: using the same file as\
            input and output might cause unexpected behaviour).
        nthreads: use this number of threads in multi-threaded applications\
            (set to 0 to disable multi-threading).
        config: temporarily set the value of an MRtrix config file entry.
        help_: display this information page and exit.
        version: display version information and exit.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "mrtrix/transformcompose",
        "info": info,
        "quiet": quiet,
        "debug": debug,
        "force": force,
        "help": help_,
        "version": version,
        "input": input_,
        "output": output,
    }
    if template is not None:
        params["template"] = template
    if nthreads is not None:
        params["nthreads"] = nthreads
    if config is not None:
        params["config"] = config
    return params


def transformcompose_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `TransformcomposeParamsDict` 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("template", None) is not None:
        if not isinstance(params["template"], (pathlib.Path, str)):
            raise StyxValidationError(f'`template` has the wrong type: Received `{type(params.get("template", None))}` expected `InputPathType | None`')
    if params.get("info", False) is None:
        raise StyxValidationError("`info` must not be None")
    if not isinstance(params["info"], bool):
        raise StyxValidationError(f'`info` has the wrong type: Received `{type(params.get("info", False))}` expected `bool`')
    if params.get("quiet", False) is None:
        raise StyxValidationError("`quiet` must not be None")
    if not isinstance(params["quiet"], bool):
        raise StyxValidationError(f'`quiet` has the wrong type: Received `{type(params.get("quiet", False))}` expected `bool`')
    if params.get("debug", False) is None:
        raise StyxValidationError("`debug` must not be None")
    if not isinstance(params["debug"], bool):
        raise StyxValidationError(f'`debug` has the wrong type: Received `{type(params.get("debug", False))}` expected `bool`')
    if params.get("force", False) is None:
        raise StyxValidationError("`force` must not be None")
    if not isinstance(params["force"], bool):
        raise StyxValidationError(f'`force` has the wrong type: Received `{type(params.get("force", False))}` expected `bool`')
    if params.get("nthreads", None) is not None:
        if not isinstance(params["nthreads"], int):
            raise StyxValidationError(f'`nthreads` has the wrong type: Received `{type(params.get("nthreads", None))}` expected `int | None`')
    if params.get("config", None) is not None:
        if not isinstance(params["config"], list):
            raise StyxValidationError(f'`config` has the wrong type: Received `{type(params.get("config", None))}` expected `list[TransformcomposeConfigParamsDict] | None`')
        for e in params["config"]:
            transformcompose_config_validate(e)
    if params.get("help", False) is None:
        raise StyxValidationError("`help` must not be None")
    if not isinstance(params["help"], bool):
        raise StyxValidationError(f'`help` has the wrong type: Received `{type(params.get("help", False))}` expected `bool`')
    if params.get("version", False) is None:
        raise StyxValidationError("`version` must not be None")
    if not isinstance(params["version"], bool):
        raise StyxValidationError(f'`version` has the wrong type: Received `{type(params.get("version", False))}` expected `bool`')
    if params.get("input", None) is None:
        raise StyxValidationError("`input` must not be None")
    if not isinstance(params["input"], list):
        raise StyxValidationError(f'`input` has the wrong type: Received `{type(params.get("input", None))}` expected `list[InputPathType]`')
    for e in params["input"]:
        if not isinstance(e, (pathlib.Path, str)):
            raise StyxValidationError(f'`input` has the wrong type: Received `{type(params.get("input", None))}` expected `list[InputPathType]`')
    if params.get("output", None) is None:
        raise StyxValidationError("`output` must not be None")
    if not isinstance(params["output"], dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params["output"])}\'')
    if "@type" not in params["output"]:
        raise StyxValidationError("Params object is missing `@type`")
    if params["output"]["@type"] not in ["VariousString", "VariousFile"]:
        raise StyxValidationError("Parameter `output`s `@type` must be one of [\"VariousString\", \"VariousFile\"]")
    transformcompose_output_validate_dyn_fn(params["output"]["@type"])(params["output"])


def transformcompose_cargs(
    params: TransformcomposeParamsDict,
    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.append("transformcompose")
    if params.get("template", None) is not None:
        cargs.extend([
            "-template",
            execution.input_file(params.get("template", None))
        ])
    if params.get("info", False):
        cargs.append("-info")
    if params.get("quiet", False):
        cargs.append("-quiet")
    if params.get("debug", False):
        cargs.append("-debug")
    if params.get("force", False):
        cargs.append("-force")
    if params.get("nthreads", None) is not None:
        cargs.extend([
            "-nthreads",
            str(params.get("nthreads", None))
        ])
    if params.get("config", None) is not None:
        cargs.extend([a for c in [transformcompose_config_cargs(s, execution) for s in params.get("config", None)] for a in c])
    if params.get("help", False):
        cargs.append("-help")
    if params.get("version", False):
        cargs.append("-version")
    cargs.extend([execution.input_file(f) for f in params.get("input", None)])
    cargs.extend(transformcompose_output_cargs_dyn_fn(params.get("output", None)["@type"])(params.get("output", None), execution))
    return cargs


def transformcompose_outputs(
    params: TransformcomposeParamsDict,
    execution: Execution,
) -> TransformcomposeOutputs:
    """
    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 = TransformcomposeOutputs(
        root=execution.output_file("."),
    )
    return ret


def transformcompose_execute(
    params: TransformcomposeParamsDict,
    runner: Runner | None = None,
) -> TransformcomposeOutputs:
    """
    transformcompose
    
    Compose any number of linear transformations and/or warps into a single
    transformation.
    
    Any linear transforms must be supplied as a 4x4 matrix in a text file (e.g.
    as per the output of mrregister). Any warp fields must be supplied as a 4D
    image representing a deformation field (e.g. as output from mrrregister
    -nl_warp).
    
    Input transformations should be provided to the command in the order in
    which they would be applied to an image if they were to be applied
    individually.
    
    If all input transformations are linear, and the -template option is not
    provided, then the file output by the command will also be a linear
    transformation saved as a 4x4 matrix in a text file. If a template image is
    supplied, then the output will always be a deformation field. If at least
    one of the inputs is a warp field, then the output will be a deformation
    field, which will be defined on the grid of the last input warp image
    supplied if the -template option is not used.
    
    References:
    
    .
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `TransformcomposeOutputs`).
    """
    transformcompose_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(TRANSFORMCOMPOSE_METADATA)
    params = execution.params(params)
    cargs = transformcompose_cargs(params, execution)
    ret = transformcompose_outputs(params, execution)
    execution.run(cargs)
    return ret


def transformcompose(
    input_: list[InputPathType],
    output: typing.Union[TransformcomposeVariousStringParamsDictTagged, TransformcomposeVariousFileParamsDictTagged],
    template: InputPathType | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[TransformcomposeConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
    runner: Runner | None = None,
) -> TransformcomposeOutputs:
    """
    transformcompose
    
    Compose any number of linear transformations and/or warps into a single
    transformation.
    
    Any linear transforms must be supplied as a 4x4 matrix in a text file (e.g.
    as per the output of mrregister). Any warp fields must be supplied as a 4D
    image representing a deformation field (e.g. as output from mrrregister
    -nl_warp).
    
    Input transformations should be provided to the command in the order in
    which they would be applied to an image if they were to be applied
    individually.
    
    If all input transformations are linear, and the -template option is not
    provided, then the file output by the command will also be a linear
    transformation saved as a 4x4 matrix in a text file. If a template image is
    supplied, then the output will always be a deformation field. If at least
    one of the inputs is a warp field, then the output will be a deformation
    field, which will be defined on the grid of the last input warp image
    supplied if the -template option is not used.
    
    References:
    
    .
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        input_: the input transforms (either linear or non-linear warps).
        output: the output file (may be a linear transformation text file, or a\
            deformation warp field image, depending on usage).
        template: define the output grid defined by a template image.
        info: display information messages.
        quiet: do not display information messages or progress status;\
            alternatively, this can be achieved by setting the MRTRIX_QUIET\
            environment variable to a non-empty string.
        debug: display debugging messages.
        force: force overwrite of output files (caution: using the same file as\
            input and output might cause unexpected behaviour).
        nthreads: use this number of threads in multi-threaded applications\
            (set to 0 to disable multi-threading).
        config: temporarily set the value of an MRtrix config file entry.
        help_: display this information page and exit.
        version: display version information and exit.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `TransformcomposeOutputs`).
    """
    params = transformcompose_params(
        template=template,
        info=info,
        quiet=quiet,
        debug=debug,
        force=force,
        nthreads=nthreads,
        config=config,
        help_=help_,
        version=version,
        input_=input_,
        output=output,
    )
    return transformcompose_execute(params, runner)


__all__ = [
    "TRANSFORMCOMPOSE_METADATA",
    "TransformcomposeConfigParamsDict",
    "TransformcomposeConfigParamsDictTagged",
    "TransformcomposeOutputs",
    "TransformcomposeParamsDict",
    "TransformcomposeParamsDictTagged",
    "TransformcomposeVariousFileParamsDict",
    "TransformcomposeVariousFileParamsDictTagged",
    "TransformcomposeVariousStringParamsDict",
    "TransformcomposeVariousStringParamsDictTagged",
    "transformcompose",
    "transformcompose_config",
    "transformcompose_execute",
    "transformcompose_params",
    "transformcompose_various_file",
    "transformcompose_various_string",
]
