# DO NOT EDIT
# This file is automatically generated by autobean_refactor.modelgen.

from typing import Iterable, Type, TypeVar, final, get_args
from .. import base, internal
from ..balance import Balance
from ..block_comment import BlockComment
from ..close import Close
from ..commodity import Commodity
from ..custom import Custom
from ..document import Document
from ..event import Event
from ..ignored_line import IgnoredLine
from ..include import Include
from ..note import Note
from ..open import Open
from ..option import Option
from ..pad import Pad
from ..plugin import Plugin
from ..popmeta import Popmeta
from ..poptag import Poptag
from ..price import Price
from ..pushmeta import Pushmeta
from ..pushtag import Pushtag
from ..query import Query
from ..spacing import Newline
from ..transaction import Transaction

Directive = Balance | Close | Commodity | Custom | Document | Event | IgnoredLine | Include | Note | Open | Option | Pad | Plugin | Popmeta | Poptag | Price | Pushmeta | Pushtag | Query | Transaction
_Self = TypeVar('_Self', bound='File')


@internal.tree_model
class File(base.RawTreeModel, internal.SpacingAccessorsMixin):
    RULE = 'file'

    _directives = internal.repeated_field[Directive | BlockComment](separators=(Newline.from_default(), Newline.from_default()), separators_before=())

    raw_directives_with_comments = internal.repeated_node_with_interleaving_comments_property[Directive | BlockComment](_directives)
    raw_directives = internal.repeated_filtered_node_property[Directive](raw_directives_with_comments, get_args(Directive))

    directives = raw_directives

    @final
    def __init__(
            self,
            token_store: base.TokenStore,
            repeated_directives: internal.Repeated[Directive | BlockComment],
    ):
        super().__init__(token_store)
        self._directives = repeated_directives

    @property
    def first_token(self) -> base.RawTokenModel:
        return self._directives.first_token

    @property
    def last_token(self) -> base.RawTokenModel:
        return self._directives.last_token

    def clone(self: _Self, token_store: base.TokenStore, token_transformer: base.TokenTransformer) -> _Self:
        return type(self)(
            token_store,
            type(self)._directives.clone(self._directives, token_store, token_transformer),
        )

    def _reattach(self, token_store: base.TokenStore, token_transformer: base.TokenTransformer) -> None:
        self._token_store = token_store
        self._directives = type(self)._directives.reattach(self._directives, token_store, token_transformer)

    def _eq(self, other: base.RawTreeModel) -> bool:
        return (
            isinstance(other, File)
            and self._directives == other._directives
        )

    @classmethod
    def from_children(
            cls: Type[_Self],
            directives: Iterable[Directive | BlockComment],
    ) -> _Self:
        repeated_directives = cls._directives.create_repeated(directives)
        tokens = [
            *cls._directives.detach_with_separators(repeated_directives),
        ]
        token_store = base.TokenStore.from_tokens(tokens)
        cls._directives.reattach(repeated_directives, token_store)
        return cls(token_store, repeated_directives)

    @classmethod
    def from_value(
            cls: Type[_Self],
            directives: Iterable[Directive],
    ) -> _Self:
        return cls.from_children(
            directives=directives,
        )

    def auto_claim_comments(self) -> None:
        self.raw_directives_with_comments.auto_claim_comments()
