"""
程序记忆 — 技能、行为模式
存储格式: memory/procedural/skills.jsonl
"""

import json
import time
from pathlib import Path


class ProceduralMemory:
    """程序记忆: 智能体学到的技能和模式"""

    def __init__(self, storage_dir: Path):
        self.storage_dir = Path(storage_dir)
        self.storage_dir.mkdir(parents=True, exist_ok=True)
        self._skills_path = self.storage_dir / "skills.jsonl"

    def add(self, skill_name: str, description: str, steps: str, tags: list = None):
        """添加一个技能"""
        entry = {
            "name": skill_name,
            "description": description,
            "steps": steps,
            "tags": tags or [],
            "created_at": time.time(),
            "success_count": 0,
        }
        with open(self._skills_path, "a", encoding="utf-8") as f:
            f.write(json.dumps(entry, ensure_ascii=False) + "\n")

    def retrieve_relevant(self, limit: int = 5) -> list[str]:
        """获取最近学到的技能"""
        skills = self._read_all()
        skills.sort(key=lambda s: s.get("success_count", 0), reverse=True)
        result = []
        for s in skills[:limit]:
            result.append(
                f"技能: {s['name']}\n"
                f"描述: {s.get('description', '')}\n"
                f"步骤: {s.get('steps', '')}"
            )
        return result

    def search(self, query: str, limit: int = 5) -> list[dict]:
        """搜索技能"""
        skills = self._read_all()
        results = []
        query_lower = query.lower()

        for s in skills:
            text = f"{s.get('name', '')} {s.get('description', '')} {s.get('steps', '')}"
            if query_lower in text.lower():
                score = text.lower().count(query_lower)
                results.append({
                    "score": score,
                    "name": s.get("name", ""),
                    "content": s.get("description", ""),
                    "steps": s.get("steps", ""),
                })

        results.sort(key=lambda r: r["score"], reverse=True)
        return results[:limit]

    def count(self) -> int:
        return len(self._read_all())

    def _read_all(self) -> list[dict]:
        if not self._skills_path.exists():
            return []
        skills = []
        with open(self._skills_path, "r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if line:
                    try:
                        skills.append(json.loads(line))
                    except json.JSONDecodeError:
                        continue
        return skills
