# Source code for matchtable.matchtable

    import json
    import os
    from typing import Any, Literal, NotRequired, Self, TypedDict

    from .column import Column, ColumnBuilder
    from .filter import Filter, FilterBuilder
    from .matchitem import MatchItem, MatchItemBuilder
    from .operation import Operation, OperationBuilder

    class Sort(TypedDict):
        columnId: str
        isDescending: bool

    class MatchResult(TypedDict):
        columns: list[Column]
        items: dict[str, MatchItem]
        defaultFilter: NotRequired[Filter]
        defaultSort: NotRequired[Sort]

    class MatchTable(TypedDict):
        formatVersion: int
        matchItemOperations: list[Operation]
        matchResult: MatchResult

    class MatchTableBuilder:
        """Create a match table."""

        def __init__(self) -> None:
            self.format_version = 1
            self.columns: list[ColumnBuilder] = []
            self.items: dict[str, MatchItemBuilder] = {}
            self.operations: list[OperationBuilder] = []
            self.default_filter: Filter | None = None
            self.default_sort: Sort | None = None

        def add_column(self, column: ColumnBuilder) -> Self:
            """Add a column to match table."""
            self.columns.append(column)
            return self

        def add_item(self, match: MatchItemBuilder) -> Self:
            """Add a match item to match table."""
            self.items[match.id] = match
            return self

        def add_operation(self, operation: OperationBuilder) -> Self:
            """Add an operation to match table."""
            self.operations.append(operation)
            return self

        def set_default_filter(self, filter_builder: FilterBuilder) -> Self:
            """Set a default filter to match table."""
            self.default_filter = filter_builder.build()
            return self

        def set_default_sort(
            self, column: ColumnBuilder, is_descending: bool
        ) -> Self:
            """Set a default sort to match table.

            Args:
                column:
                    The column to be sorted.
                is_descending:
                    Whether sort in descending order or not.
            """
            self.default_sort = Sort(
                columnId=column.id, isDescending=is_descending
            )
            return self

        def build(self) -> MatchTable:
            """Obtain the data."""
            items: dict[str, MatchItem] = {}
            for m_id in self.items:
                items[m_id] = self.items[m_id].build()
            match_result = MatchResult(
                columns=[c.build() for c in self.columns],
                items=items,
            )
            match_result_optional_keys: dict[
                Literal["defaultFilter", "defaultSort"], Any
            ] = {
                "defaultFilter": self.default_filter,
                "defaultSort": self.default_sort,
            }
            for key, val in match_result_optional_keys.items():
                if val is not None:
                    match_result[key] = val
            return MatchTable(
                formatVersion=self.format_version,
                matchResult=match_result,
                matchItemOperations=[op.build() for op in self.operations],
            )

    class MatchTableWriter:
        """A writer for the matchtable."""

        def __init__(self, matchtable: MatchTable):
            self.matchtable = matchtable

        def write(self, filepath: str) -> bool:
            """Write matchtable.json to filepath.

            Args:
                filepath:
                    Output file path.

            Returns:
                bool:
                    Is writing success or fail.
            """
            try:
                os.makedirs(os.path.dirname(filepath), exist_ok=True)
                with open(filepath, "w") as f:
                    json.dump(self.matchtable, f, allow_nan=False)
                return True
            except Exception:
                return False