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

import typing
import pathlib
from styxdefs import *

LABEL_TO_BORDER_METADATA = Metadata(
    id="73238edbf5a2ddc85d7db5f72cf5459fa04f8d95.workbench",
    name="label-to-border",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_LabelToBorderParamsDictNoTag = typing.TypedDict('_LabelToBorderParamsDictNoTag', {
    "surface": InputPathType,
    "label-in": InputPathType,
    "border-out": str,
    "column": typing.NotRequired[str | None],
    "fraction": typing.NotRequired[float | None],
})
LabelToBorderParamsDictTagged = typing.TypedDict('LabelToBorderParamsDictTagged', {
    "@type": typing.Literal["workbench/label-to-border"],
    "surface": InputPathType,
    "label-in": InputPathType,
    "border-out": str,
    "column": typing.NotRequired[str | None],
    "fraction": typing.NotRequired[float | None],
})
LabelToBorderParamsDict = _LabelToBorderParamsDictNoTag | LabelToBorderParamsDictTagged


class LabelToBorderOutputs(typing.NamedTuple):
    """
    Output object returned when calling `LabelToBorderParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    border_out: OutputPathType
    """the output border file"""


def label_to_border_params(
    surface: InputPathType,
    label_in: InputPathType,
    border_out: str,
    column: str | None = None,
    fraction: float | None = None,
) -> LabelToBorderParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the surface to use for neighbor information.
        label_in: the input label file.
        border_out: the output border file.
        column: select a single column\
            \
            the column number or name.
        fraction: set how far along the edge border points are drawn\
            \
            fraction along edge from inside vertex (default 0.33).
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/label-to-border",
        "surface": surface,
        "label-in": label_in,
        "border-out": border_out,
    }
    if column is not None:
        params["column"] = column
    if fraction is not None:
        params["fraction"] = fraction
    return params


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


def label_to_border_cargs(
    params: LabelToBorderParamsDict,
    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",
        "-label-to-border"
    ])
    cargs.append(execution.input_file(params.get("surface", None)))
    cargs.append(execution.input_file(params.get("label-in", None)))
    cargs.append(params.get("border-out", None))
    if params.get("column", None) is not None:
        cargs.extend([
            "-column",
            params.get("column", None)
        ])
    if params.get("fraction", None) is not None:
        cargs.extend([
            "-placement",
            str(params.get("fraction", None))
        ])
    return cargs


def label_to_border_outputs(
    params: LabelToBorderParamsDict,
    execution: Execution,
) -> LabelToBorderOutputs:
    """
    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 = LabelToBorderOutputs(
        root=execution.output_file("."),
        border_out=execution.output_file(params.get("border-out", None)),
    )
    return ret


def label_to_border_execute(
    params: LabelToBorderParamsDict,
    runner: Runner | None = None,
) -> LabelToBorderOutputs:
    """
    DRAW BORDERS AROUND LABELS.
    
    For each label, finds all edges on the mesh that cross the boundary of the
    label, and draws borders through them. By default, this is done on all
    columns in the input file, using the map name as the class name for the
    border.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `LabelToBorderOutputs`).
    """
    label_to_border_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(LABEL_TO_BORDER_METADATA)
    params = execution.params(params)
    cargs = label_to_border_cargs(params, execution)
    ret = label_to_border_outputs(params, execution)
    execution.run(cargs)
    return ret


def label_to_border(
    surface: InputPathType,
    label_in: InputPathType,
    border_out: str,
    column: str | None = None,
    fraction: float | None = None,
    runner: Runner | None = None,
) -> LabelToBorderOutputs:
    """
    DRAW BORDERS AROUND LABELS.
    
    For each label, finds all edges on the mesh that cross the boundary of the
    label, and draws borders through them. By default, this is done on all
    columns in the input file, using the map name as the class name for the
    border.
    
    Args:
        surface: the surface to use for neighbor information.
        label_in: the input label file.
        border_out: the output border file.
        column: select a single column\
            \
            the column number or name.
        fraction: set how far along the edge border points are drawn\
            \
            fraction along edge from inside vertex (default 0.33).
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `LabelToBorderOutputs`).
    """
    params = label_to_border_params(
        surface=surface,
        label_in=label_in,
        border_out=border_out,
        column=column,
        fraction=fraction,
    )
    return label_to_border_execute(params, runner)


__all__ = [
    "LABEL_TO_BORDER_METADATA",
    "LabelToBorderOutputs",
    "LabelToBorderParamsDict",
    "LabelToBorderParamsDictTagged",
    "label_to_border",
    "label_to_border_execute",
    "label_to_border_params",
]
