"""显式偏好的生命周期模拟。没有自然语言提取、数据库或向量索引。"""
from dataclasses import dataclass, replace


@dataclass(frozen=True)
class Memory:
    namespace: tuple[str, str, str]
    version: int
    value: str
    source_event: str
    status: str = "active"


class MemoryStore:
    def __init__(self) -> None:
        # 主记录保留版本变化；事件集合用于阻止旧事件重复写入。
        self.rows: list[Memory] = []
        self.seen: set[tuple[tuple[str, str, str], str]] = set()

    def put(self, namespace: tuple[str, str, str], value: str,
            event: str, *, explicit_long_term: bool) -> None:
        if not explicit_long_term:
            raise ValueError("本次要求不自动升级为长期偏好")
        identity = (namespace, event)
        if identity in self.seen:
            return
        # 本例只接收已经按来源顺序处理的事件；异步乱序需另做版本检查。
        # namespace 由服务端调用者确定，不能由模型填写目标用户。
        versions = [m.version for m in self.rows if m.namespace == namespace]
        self.rows = [replace(m, status="superseded")
                     if m.namespace == namespace and m.status == "active" else m
                     for m in self.rows]
        self.rows.append(Memory(namespace, max(versions, default=0) + 1, value, event))
        self.seen.add(identity)

    def read(self, namespace: tuple[str, str, str]) -> Memory | None:
        # 精确偏好按键读取，不需要为了使用向量库而加入语义检索。
        return next((m for m in reversed(self.rows)
                     if m.namespace == namespace and m.status == "active"), None)

    def forget(self, namespace: tuple[str, str, str]) -> None:
        # 演示将所有旧版正文清空并标记删除；保留事件去重控制记录。
        # 正式系统还需清理外部索引、缓存、摘要及按策略处理备份。
        self.rows = [replace(m, value="", status="deleted")
                     if m.namespace == namespace else m for m in self.rows]


if __name__ == "__main__":
    store = MemoryStore()
    scope = ("shop-a", "user-417", "code_language")
    store.put(scope, "Java", "U30", explicit_long_term=True)
    store.put(scope, "Python", "U31", explicit_long_term=True)
    store.put(scope, "Python", "U31", explicit_long_term=True)
    print(store.read(scope))
    store.forget(scope)
    store.put(scope, "Java", "U30", explicit_long_term=True)
    print(store.read(scope))  # 设计预期为 None，旧事件不会复活已删除偏好。
