#!/usr/bin/env python3
"""
KnowHub CLI - 知识管理命令行工具

使用方法:
    python -m knowhub.skill.cli search "查询内容"
    python -m knowhub.skill.cli save --task "任务" --content "内容" --types strategy
    python -m knowhub.skill.cli list --limit 10
"""

import os
import sys
import json
import argparse
from pathlib import Path

try:
    import httpx
except ImportError:
    print("错误: 需要安装 httpx 库")
    print("运行: pip install httpx")
    sys.exit(1)

# KnowHub API 默认地址（CLI 需要在开头声明，方便用户查看和修改）
DEFAULT_API_URL = "http://43.106.118.91:9999"


def get_api_base() -> str:
    """获取 API 地址"""
    return os.getenv("KNOWHUB_API", DEFAULT_API_URL)


def search_knowledge(args):
    """搜索知识"""
    url = f"{get_api_base()}/api/knowledge/search"
    params = {
        "q": args.query,
        "top_k": args.top_k,
        "min_score": args.min_score,
    }
    if args.types:
        params["types"] = args.types

    try:
        response = httpx.get(url, params=params, timeout=30.0)
        response.raise_for_status()
        data = response.json()

        if data["count"] == 0:
            print("未找到相关知识")
            return

        print(f"找到 {data['count']} 条知识:\n")
        for i, item in enumerate(data["results"], 1):
            print(f"[{i}] {item['task']}")
            print(f"    ID: {item['id']}")
            eval_data = item.get("eval", {})
            print(f"    评分: {eval_data.get('score', 3)} | 质量分: {item.get('quality_score', 'N/A')}")
            print(f"    类型: {', '.join(item.get('types', []))}")
            print(f"    内容: {item['content'][:100]}...")
            print()

    except httpx.HTTPError as e:
        print(f"请求失败: {e}")
        sys.exit(1)


def save_knowledge(args):
    """保存知识"""
    url = f"{get_api_base()}/api/knowledge"

    data = {
        "message_id": args.message_id or f"cli-{os.getpid()}",
        "types": args.types.split(",") if args.types else ["strategy"],
        "task": args.task,
        "tags": json.loads(args.tags) if args.tags else {},
        "scopes": args.scopes.split(",") if args.scopes else ["org:cybertogether"],
        "owner": args.owner or "agent:cli",
        "content": args.content,
        "source": {
            "name": args.source_name or "cli",
            "category": args.source_category or "exp",
            "urls": args.urls.split(",") if args.urls else [],
            "agent_id": args.agent_id or "cli",
            "submitted_by": args.submitted_by or "cli-user",
        },
        "eval": {
            "score": args.score,
            "helpful": 1,
            "harmful": 0,
            "confidence": 0.5,
        }
    }

    try:
        response = httpx.post(url, json=data, timeout=30.0)
        response.raise_for_status()
        result = response.json()
        print(f"✅ 知识已保存: {result['knowledge_id']}")

    except httpx.HTTPError as e:
        print(f"保存失败: {e}")
        sys.exit(1)


def update_knowledge(args):
    """更新知识"""
    url = f"{get_api_base()}/api/knowledge/{args.id}"

    data = {}
    if args.score:
        data["update_score"] = args.score
    if args.helpful_case:
        data["add_helpful_case"] = args.helpful_case
    if args.harmful_case:
        data["add_harmful_case"] = args.harmful_case
    if args.evolve_feedback:
        data["evolve_feedback"] = args.evolve_feedback

    if not data:
        print("错误: 至少需要提供一个更新参数")
        sys.exit(1)

    try:
        response = httpx.put(url, json=data, timeout=30.0)
        response.raise_for_status()
        print(f"✅ 知识已更新: {args.id}")

    except httpx.HTTPError as e:
        print(f"更新失败: {e}")
        sys.exit(1)


def batch_update_knowledge(args):
    """批量更新知识"""
    url = f"{get_api_base()}/api/knowledge/batch_update"

    # 从文件读取反馈列表
    if args.file:
        with open(args.file, 'r') as f:
            feedback_list = json.load(f)
    else:
        print("错误: 需要提供 --file 参数")
        sys.exit(1)

    data = {"feedback_list": feedback_list}

    try:
        response = httpx.post(url, json=data, timeout=60.0)
        response.raise_for_status()
        result = response.json()
        print(f"✅ 批量更新完成: {result['updated']} 条知识")

    except httpx.HTTPError as e:
        print(f"批量更新失败: {e}")
        sys.exit(1)


def list_knowledge(args):
    """列出知识"""
    url = f"{get_api_base()}/api/knowledge"
    params = {"limit": args.limit}
    if args.types:
        params["types"] = args.types
    if args.scopes:
        params["scopes"] = args.scopes

    try:
        response = httpx.get(url, params=params, timeout=30.0)
        response.raise_for_status()
        data = response.json()

        if data["count"] == 0:
            print("知识库为空")
            return

        print(f"共 {data['count']} 条知识:\n")
        for i, item in enumerate(data["results"], 1):
            print(f"[{i}] {item['task']}")
            print(f"    ID: {item['id']}")
            eval_data = item.get("eval", {})
            print(f"    评分: {eval_data.get('score', 3)} | Helpful: {eval_data.get('helpful', 0)} | Harmful: {eval_data.get('harmful', 0)}")
            print(f"    类型: {', '.join(item.get('types', []))}")
            print(f"    所有者: {item.get('owner', 'N/A')}")
            print()

    except httpx.HTTPError as e:
        print(f"请求失败: {e}")
        sys.exit(1)


def slim_knowledge(args):
    """知识瘦身"""
    url = f"{get_api_base()}/api/knowledge/slim"
    params = {"model": args.model}

    try:
        print("正在执行知识瘦身，这可能需要一些时间...")
        response = httpx.post(url, params=params, timeout=120.0)
        response.raise_for_status()
        result = response.json()
        print(f"✅ 瘦身完成: {result['before']} → {result['after']} 条知识")
        if result.get("report"):
            print(f"   {result['report']}")

    except httpx.HTTPError as e:
        print(f"瘦身失败: {e}")
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(description="KnowHub CLI - 知识管理工具")
    subparsers = parser.add_subparsers(dest="command", help="可用命令")

    # search 命令
    search_parser = subparsers.add_parser("search", help="搜索知识")
    search_parser.add_argument("query", help="查询文本")
    search_parser.add_argument("--top-k", type=int, default=5, help="返回结果数量")
    search_parser.add_argument("--min-score", type=int, default=3, help="最低评分")
    search_parser.add_argument("--types", help="类型过滤（逗号分隔）")

    # save 命令
    save_parser = subparsers.add_parser("save", help="保存知识")
    save_parser.add_argument("--task", required=True, help="任务描述")
    save_parser.add_argument("--content", required=True, help="知识内容")
    save_parser.add_argument("--types", default="strategy", help="类型（逗号分隔）")
    save_parser.add_argument("--tags", help="标签（JSON 格式）")
    save_parser.add_argument("--scopes", help="可见范围（逗号分隔）")
    save_parser.add_argument("--owner", help="所有者")
    save_parser.add_argument("--source-name", help="来源名称")
    save_parser.add_argument("--source-category", help="来源类别")
    save_parser.add_argument("--urls", help="相关 URL（逗号分隔）")
    save_parser.add_argument("--agent-id", help="Agent ID")
    save_parser.add_argument("--submitted-by", help="提交者")
    save_parser.add_argument("--message-id", help="消息 ID")
    save_parser.add_argument("--score", type=int, default=3, help="评分 (1-5)")

    # update 命令
    update_parser = subparsers.add_parser("update", help="更新知识")
    update_parser.add_argument("id", help="知识 ID")
    update_parser.add_argument("--score", type=int, help="更新评分")
    update_parser.add_argument("--helpful-case", help="添加有效案例")
    update_parser.add_argument("--harmful-case", help="添加有害案例")
    update_parser.add_argument("--evolve-feedback", help="知识进化反馈")

    # batch-update 命令
    batch_parser = subparsers.add_parser("batch-update", help="批量更新知识")
    batch_parser.add_argument("--file", required=True, help="反馈列表 JSON 文件")

    # list 命令
    list_parser = subparsers.add_parser("list", help="列出知识")
    list_parser.add_argument("--limit", type=int, default=10, help="返回数量")
    list_parser.add_argument("--types", help="类型过滤")
    list_parser.add_argument("--scopes", help="范围过滤")

    # slim 命令
    slim_parser = subparsers.add_parser("slim", help="知识瘦身")
    slim_parser.add_argument("--model", default="google/gemini-2.0-flash-001", help="使用的模型")

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        sys.exit(1)

    # 执行命令
    if args.command == "search":
        search_knowledge(args)
    elif args.command == "save":
        save_knowledge(args)
    elif args.command == "update":
        update_knowledge(args)
    elif args.command == "batch-update":
        batch_update_knowledge(args)
    elif args.command == "list":
        list_knowledge(args)
    elif args.command == "slim":
        slim_knowledge(args)


if __name__ == "__main__":
    main()

