# -*- coding: utf-8 -*-
"""Un faux client API qui rejoue un scénario, pour éprouver la mécanique
sans dépenser un jeton. Reproduit la forme des objets du SDK : blocs de
contenu typés, stop_reason, usage, to_dict() et le gestionnaire de flux."""


class Bloc:
    def __init__(self, **kw):
        self.__dict__.update(kw)

    def to_dict(self):
        return {k: v for k, v in self.__dict__.items() if v is not None}


def texte(t):
    return Bloc(type="text", text=t)


def reflexion(t=""):
    return Bloc(type="thinking", thinking=t, signature="sig-factice")


def appel(id_, nom, entree):
    return Bloc(type="tool_use", id=id_, name=nom, input=entree)


class Usage:
    def __init__(self):
        self.input_tokens = 900
        self.output_tokens = 4200
        self.cache_read_input_tokens = 61000
        self.cache_creation_input_tokens = 0


class Reponse:
    def __init__(self, contenu, stop_reason, stop_details=None):
        self.content = contenu
        self.stop_reason = stop_reason
        self.stop_details = stop_details
        self.usage = Usage()

    def to_dict(self):
        return {"content": [b.to_dict() for b in self.content]}


class _Flux:
    def __init__(self, reponse):
        self._reponse = reponse

    def __enter__(self):
        return self

    def __exit__(self, *a):
        return False

    def get_final_message(self):
        return self._reponse


class FauxClient:
    """Rejoue une liste de réponses. Enregistre chaque requête reçue pour
    qu'on puisse vérifier le cache, les outils et la forme des messages."""

    def __init__(self, scenario):
        self.scenario = list(scenario)
        self.requetes = []
        self.messages = self
        self.position = 0

    def stream(self, **kw):
        self.requetes.append(kw)
        if self.position >= len(self.scenario):
            raise AssertionError("scénario épuisé : un tour de trop")
        element = self.scenario[self.position]
        self.position += 1
        if isinstance(element, Exception):
            raise element
        return _Flux(element)
