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

import typing
import pathlib
from styxdefs import *

BORDER_MERGE_METADATA = Metadata(
    id="2b501fbb7f7c4f9515ae97ae16a101a97a54eaab.workbench",
    name="border-merge",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_BorderMergeUpToParamsDictNoTag = typing.TypedDict('_BorderMergeUpToParamsDictNoTag', {
    "last-border": str,
    "reverse": bool,
})
BorderMergeUpToParamsDictTagged = typing.TypedDict('BorderMergeUpToParamsDictTagged', {
    "@type": typing.Literal["up-to"],
    "last-border": str,
    "reverse": bool,
})
BorderMergeUpToParamsDict = _BorderMergeUpToParamsDictNoTag | BorderMergeUpToParamsDictTagged


_BorderMergeSelectParamsDictNoTag = typing.TypedDict('_BorderMergeSelectParamsDictNoTag', {
    "border": str,
    "up-to": typing.NotRequired[BorderMergeUpToParamsDict | None],
})
BorderMergeSelectParamsDictTagged = typing.TypedDict('BorderMergeSelectParamsDictTagged', {
    "@type": typing.Literal["select"],
    "border": str,
    "up-to": typing.NotRequired[BorderMergeUpToParamsDict | None],
})
BorderMergeSelectParamsDict = _BorderMergeSelectParamsDictNoTag | BorderMergeSelectParamsDictTagged


_BorderMergeBorderParamsDictNoTag = typing.TypedDict('_BorderMergeBorderParamsDictNoTag', {
    "border-file-in": InputPathType,
    "select": typing.NotRequired[list[BorderMergeSelectParamsDict] | None],
})
BorderMergeBorderParamsDictTagged = typing.TypedDict('BorderMergeBorderParamsDictTagged', {
    "@type": typing.Literal["border"],
    "border-file-in": InputPathType,
    "select": typing.NotRequired[list[BorderMergeSelectParamsDict] | None],
})
BorderMergeBorderParamsDict = _BorderMergeBorderParamsDictNoTag | BorderMergeBorderParamsDictTagged


_BorderMergeParamsDictNoTag = typing.TypedDict('_BorderMergeParamsDictNoTag', {
    "border-file-out": str,
    "border": typing.NotRequired[list[BorderMergeBorderParamsDict] | None],
})
BorderMergeParamsDictTagged = typing.TypedDict('BorderMergeParamsDictTagged', {
    "@type": typing.Literal["workbench/border-merge"],
    "border-file-out": str,
    "border": typing.NotRequired[list[BorderMergeBorderParamsDict] | None],
})
BorderMergeParamsDict = _BorderMergeParamsDictNoTag | BorderMergeParamsDictTagged


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


def border_merge_up_to_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `BorderMergeUpToParamsDict` 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-border", None) is None:
        raise StyxValidationError("`last-border` must not be None")
    if not isinstance(params["last-border"], str):
        raise StyxValidationError(f'`last-border` has the wrong type: Received `{type(params.get("last-border", 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 border_merge_up_to_cargs(
    params: BorderMergeUpToParamsDict,
    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-border", None)
    ])
    if params.get("reverse", False):
        cargs.append("-reverse")
    return cargs


def border_merge_select(
    border: str,
    up_to: BorderMergeUpToParamsDict | None = None,
) -> BorderMergeSelectParamsDictTagged:
    """
    Build parameters.
    
    Args:
        border: the border number or name.
        up_to: use an inclusive range of borders.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "select",
        "border": border,
    }
    if up_to is not None:
        params["up-to"] = up_to
    return params


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


def border_merge_select_cargs(
    params: BorderMergeSelectParamsDict,
    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([
        "-select",
        params.get("border", None),
        *(border_merge_up_to_cargs(params.get("up-to", None), execution) if (params.get("up-to", None) is not None) else [])
    ])
    return cargs


def border_merge_border(
    border_file_in: InputPathType,
    select_: list[BorderMergeSelectParamsDict] | None = None,
) -> BorderMergeBorderParamsDictTagged:
    """
    Build parameters.
    
    Args:
        border_file_in: a border file to use borders from.
        select_: select a single border to use.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "border",
        "border-file-in": border_file_in,
    }
    if select_ is not None:
        params["select"] = select_
    return params


def border_merge_border_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `BorderMergeBorderParamsDict` 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("border-file-in", None) is None:
        raise StyxValidationError("`border-file-in` must not be None")
    if not isinstance(params["border-file-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`border-file-in` has the wrong type: Received `{type(params.get("border-file-in", None))}` expected `InputPathType`')
    if params.get("select", None) is not None:
        if not isinstance(params["select"], list):
            raise StyxValidationError(f'`select` has the wrong type: Received `{type(params.get("select", None))}` expected `list[BorderMergeSelectParamsDict] | None`')
        for e in params["select"]:
            border_merge_select_validate(e)


def border_merge_border_cargs(
    params: BorderMergeBorderParamsDict,
    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([
        "-border",
        execution.input_file(params.get("border-file-in", None)),
        *([a for c in [border_merge_select_cargs(s, execution) for s in params.get("select", None)] for a in c] if (params.get("select", None) is not None) else [])
    ])
    return cargs


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


def border_merge_params(
    border_file_out: str,
    border: list[BorderMergeBorderParamsDict] | None = None,
) -> BorderMergeParamsDictTagged:
    """
    Build parameters.
    
    Args:
        border_file_out: the output border file.
        border: specify an input border file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/border-merge",
        "border-file-out": border_file_out,
    }
    if border is not None:
        params["border"] = border
    return params


def border_merge_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `BorderMergeParamsDict` 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("border-file-out", None) is None:
        raise StyxValidationError("`border-file-out` must not be None")
    if not isinstance(params["border-file-out"], str):
        raise StyxValidationError(f'`border-file-out` has the wrong type: Received `{type(params.get("border-file-out", None))}` expected `str`')
    if params.get("border", None) is not None:
        if not isinstance(params["border"], list):
            raise StyxValidationError(f'`border` has the wrong type: Received `{type(params.get("border", None))}` expected `list[BorderMergeBorderParamsDict] | None`')
        for e in params["border"]:
            border_merge_border_validate(e)


def border_merge_cargs(
    params: BorderMergeParamsDict,
    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",
        "-border-merge"
    ])
    cargs.append(params.get("border-file-out", None))
    if params.get("border", None) is not None:
        cargs.extend([a for c in [border_merge_border_cargs(s, execution) for s in params.get("border", None)] for a in c])
    return cargs


def border_merge_outputs(
    params: BorderMergeParamsDict,
    execution: Execution,
) -> BorderMergeOutputs:
    """
    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 = BorderMergeOutputs(
        root=execution.output_file("."),
        border_file_out=execution.output_file(params.get("border-file-out", None)),
    )
    return ret


def border_merge_execute(
    params: BorderMergeParamsDict,
    runner: Runner | None = None,
) -> BorderMergeOutputs:
    """
    MERGE BORDER FILES INTO A NEW FILE.
    
    Takes one or more border files and makes a new border file from the borders
    in them.
    
    Example: wb_command -border-merge out.border -border first.border -select 1
    -border second.border
    
    This example would take the first border from first.border, followed by all
    borders from second.border, and write these to out.border.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `BorderMergeOutputs`).
    """
    border_merge_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(BORDER_MERGE_METADATA)
    params = execution.params(params)
    cargs = border_merge_cargs(params, execution)
    ret = border_merge_outputs(params, execution)
    execution.run(cargs)
    return ret


def border_merge(
    border_file_out: str,
    border: list[BorderMergeBorderParamsDict] | None = None,
    runner: Runner | None = None,
) -> BorderMergeOutputs:
    """
    MERGE BORDER FILES INTO A NEW FILE.
    
    Takes one or more border files and makes a new border file from the borders
    in them.
    
    Example: wb_command -border-merge out.border -border first.border -select 1
    -border second.border
    
    This example would take the first border from first.border, followed by all
    borders from second.border, and write these to out.border.
    
    Args:
        border_file_out: the output border file.
        border: specify an input border file.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `BorderMergeOutputs`).
    """
    params = border_merge_params(
        border_file_out=border_file_out,
        border=border,
    )
    return border_merge_execute(params, runner)


__all__ = [
    "BORDER_MERGE_METADATA",
    "BorderMergeBorderParamsDict",
    "BorderMergeBorderParamsDictTagged",
    "BorderMergeOutputs",
    "BorderMergeParamsDict",
    "BorderMergeParamsDictTagged",
    "BorderMergeSelectParamsDict",
    "BorderMergeSelectParamsDictTagged",
    "BorderMergeUpToParamsDict",
    "BorderMergeUpToParamsDictTagged",
    "border_merge",
    "border_merge_border",
    "border_merge_execute",
    "border_merge_params",
    "border_merge_select",
    "border_merge_up_to",
]
