# AUTOGENERATED! DO NOT EDIT! File to edit: ../src/quote.ipynb.

# %% auto 0
__all__ = ['QUOTER_STABLE_POOL_FILLER', 'QUOTER_VOLATILE_POOL_FILLER', 'PreparedRoute', 'pack_path', 'QuoteInput', 'Quote']

# %% ../src/quote.ipynb 3
from functools import reduce
from typing import List, Union, Tuple
from eth_abi.packed import encode_packed
from dataclasses import dataclass
from .token import Token
from .pool import LiquidityPoolForSwap

# %% ../src/quote.ipynb 4
# magic numbers
QUOTER_STABLE_POOL_FILLER, QUOTER_VOLATILE_POOL_FILLER = 2097152, 4194304

@dataclass
class PreparedRoute:
    types: List[str]; values: List[Union[str, int]]

    @property
    def encoded(self) -> bytes: return encode_packed(self.types, self.values)

def pack_path(path: List[Tuple[LiquidityPoolForSwap, bool]]) -> PreparedRoute:
    types, values = reduce(lambda s, pool: s + pool, [["address", "int24"] for i in range(len(path))], []) + ["address"], []
    for node in path:
        pool, reversed = node
        token0, token1 = pool.token0_address if not reversed else pool.token1_address, pool.token1_address if not reversed else pool.token0_address
        if pool.type > 0: filler = pool.type
        else: filler =  QUOTER_STABLE_POOL_FILLER if pool.is_stable else QUOTER_VOLATILE_POOL_FILLER
        if len(values) == 0: values = [token0, filler, token1]
        else: values += [filler, token1]
    return PreparedRoute(types=types, values=values)

@dataclass
class QuoteInput:
    from_token: Token; to_token: Token; path: List[Tuple[LiquidityPoolForSwap, bool]]; amount_in: int

    def to_tuple(self) -> tuple: return (self.from_token, self.to_token, tuple(self.path), self.amount_in, self.amount_out)

    @staticmethod
    def from_tuple(t: tuple) -> "QuoteInput":
        from_token, to_token, path, amount_in, amount_out = t
        return QuoteInput(from_token=from_token, to_token=to_token, path=list(path), amount_in=amount_in, amount_out=amount_out)
    
    @property
    def route(self) -> PreparedRoute: return pack_path(self.path)

@dataclass
class Quote:
    input: QuoteInput; amount_out: int

    @property
    def from_token(self) -> Token: return self.input.from_token
    @property
    def to_token(self) -> Token: return self.input.to_token
    @property
    def path(self) -> List[Tuple[LiquidityPoolForSwap, bool]]: return self.input.path
    @property
    def amount_in(self) -> int: return self.input.amount_in
