"""
This type stub file was generated by pyright.
"""

from abc import ABCMeta, abstractmethod
from collections.abc import Iterator, Mapping, Sequence
from typing import Any, Optional, TypeVar, Generic, Self
from amaranth.hdl import *
import amaranth.hdl as hdl
from amaranth.hdl._ast import Assign, ShapeCastable, ValueCastable, Format, _FormatLike
from amaranth_types import ShapeLike, ValueLike

__all__ = ["Field", "Layout", "StructLayout", "UnionLayout", "ArrayLayout", "FlexibleLayout", "View", "Const", "Struct", "Union"]


_T_ShapeCastable = TypeVar("_T_ShapeCastable", bound=ShapeCastable, covariant=True)


class Field:
    def __init__(self, shape: ShapeLike, offset: int) -> None:
        ...
    
    @property
    def shape(self) -> ShapeLike:
        ...
    
    @property
    def offset(self) -> int:
        ...
    
    @property
    def width(self) -> int:
        ...
    
    def __eq__(self, other) -> bool:
        ...
    
    def __repr__(self) -> str:
        ...
    


class Layout(ShapeCastable[View[Self]], metaclass=ABCMeta):
    @staticmethod
    def cast(obj: ShapeCastable) -> Layout:
        """Cast a shape-castable object to a layout."""
        ...
    
    @abstractmethod
    def __iter__(self) -> Iterator[tuple[int | str, Field]]:
        """Iterate the layout, yielding ``(key, field)`` pairs. Keys may be strings or integers."""
        ...
    
    @abstractmethod
    def __getitem__(self, key: int | str) -> Field:
        """Retrieve the :class:`Field` associated with the ``key``, or raise ``KeyError``."""
        ...
    
    def size(self) -> int:
        """Size of the layout."""
        ...

    def as_shape(self) -> Shape:
        """Convert the representation defined by the layout to an unsigned :class:`Shape`."""
        ...
    
    def __eq__(self, other) -> bool:
        """Compare the layout with another.

        Two layouts are equal if they have the same size and the same fields under the same names.
        The order of the fields is not considered.
        """
        ...

    def __call__(self, target: ValueLike) -> View[Self]:
        """Create a view into a target."""
        ...

    def const(self, init: Optional[Sequence[Any] | Mapping[int | str, Any]]) -> Const:
        """Convert a constant initializer to a constant."""
        ...

    def from_bits(self, raw: int) -> Const:
        ...

    def format(self, value: ValueLike, format_spec: str) -> Format.Struct:
        ...


class StructLayout(Layout):
    def __init__(self, members: Mapping[str, ShapeLike]) -> None:
        ...
    
    @property
    def members(self) -> dict[str, ShapeLike]:
        ...
    
    def __iter__(self) -> Iterator[tuple[str, Field]]:
        ...
    
    def __getitem__(self, key: str) -> Field:
        ...
    
    @property
    def size(self) -> int:
        ...
    
    def __repr__(self) -> str:
        ...
    


class UnionLayout(Layout):
    def __init__(self, members: Mapping[str, ShapeLike]) -> None:
        ...
    
    @property
    def members(self) -> dict[str, ShapeLike]:
        ...
    
    def __iter__(self) -> Iterator[tuple[str, Field]]:
        ...
    
    def __getitem__(self, key: str) -> Field:
        ...
    
    @property
    def size(self) -> int:
        ...
    
    def __repr__(self) -> str:
        ...
    


class ArrayLayout(Layout):
    def __init__(self, elem_shape: ShapeLike, length: int) -> None:
        ...
    
    @property
    def elem_shape(self) -> ShapeLike:
        ...
    
    @property
    def length(self) -> int:
        ...
    
    def __iter__(self) -> Iterator[tuple[int, Field]]:
        ...
    
    def __getitem__(self, key: int) -> Field:
        ...
    
    @property
    def size(self) -> int:
        ...
    
    def __repr__(self) -> str:
        ...

    def format(self, value: ValueLike, format_spec: str) -> Format.Array:
        ...
    


class FlexibleLayout(Layout):
    def __init__(self, size: int, fields: Mapping[int | str, Field]) -> None:
        ...
    
    @property
    def size(self) -> int:
        ...
    
    @property
    def fields(self) -> dict[int | str, Field]:
        ...
    
    def __iter__(self) -> Iterator[tuple[int | str, Field]]:
        ...
    
    def __getitem__(self, key: int | str) -> Field:
        ...
    
    def __repr__(self) -> str:
        ...
    


class View(ValueCastable, Generic[_T_ShapeCastable]):
    def __init__(self, layout: _T_ShapeCastable, target: ValueLike) -> None:
        ...
    
    @ValueCastable.lowermethod
    def as_value(self) -> Value:
        ...
    
    def shape(self) -> _T_ShapeCastable:
        ...

    def eq(self, other: ValueLike) -> Assign:
        ...
    
    def __getitem__(self, key: str | ValueLike):  # having a defined type hard to work with
        ...
    
    def __getattr__(self, name: str):  # having a defined type hard to work with
        ...
   
    def __len__(self) -> int:
        ...

    def __eq__(self, other) -> bool:
        ...


class _AggregateMeta(ShapeCastable[Self], type):
    def __new__(metacls, name, bases, namespace, *, _layout_cls=..., **kwargs): # -> Self@_AggregateMeta:
        ...
    
    def as_shape(cls):
        ...

    def const(cls, init):
        ...

    def from_bits(cls, bits):
        ...

    def format(self, value: ValueLike, format_spec: str) -> _FormatLike:
        ...


class Const(ValueCastable, Generic[_T_ShapeCastable]):
    def __init__(self, layout: _T_ShapeCastable, target: int) -> None:
        ...

    def shape(self) -> _T_ShapeCastable:
        ...

    def as_bits(self) -> int:
        ...

    def as_value(self) -> hdl.Const:
        ...

    def __getitem__(self, key: int | str | ValueCastable) -> Any:
        ...

    def __getattr__(self, name: str) -> Any:
        ...

    def __len__(self) -> int:
        ...

    def __eq__(self, other) -> bool:
        ...

    def __ne__(self, other) -> bool:
        ...

    def __repr__(self) -> str:
        ...


class Struct(View, metaclass=_AggregateMeta):
    ...


class Union(View, metaclass=_AggregateMeta):
    ...


