package eino

import "testing"

func TestParseOps(t *testing.T) {
	got := parseOps("```json\n[{\"op\":\"ADD\",\"key\":\"称呼\",\"value\":\"Dexter\",\"importance\":7},{\"op\":\"DELETE\",\"key\":\"旧公司\"}]\n```")
	if len(got) != 2 || got[0].Op != "ADD" || got[0].Key != "称呼" || got[0].Importance != 7 || got[1].Op != "DELETE" {
		t.Fatalf("parseOps 解析错: %+v", got)
	}
	if parseOps("不是 JSON") != nil {
		t.Error("非 JSON 应返回 nil")
	}
}

func TestSanitizeOps(t *testing.T) {
	existing := map[string]string{"语言": "中文", "旧公司": "A厂"}
	in := []memOp{
		{Op: "add", Key: "重要事", Value: "X", Importance: 99}, // 大小写规范 + importance 夹到 10
		{Op: "UPDATE", Key: "语言", Value: "英文", Importance: 0}, // importance 提到 1
		{Op: "ADD", Key: "空值", Value: ""},                     // 无 value → 丢
		{Op: "DELETE", Key: "旧公司"},                            // 命中已有 → 留
		{Op: "DELETE", Key: "不存在"},                            // 未命中 → 丢（防幻删）
		{Op: "NOOP", Key: "语言"},                               // NOOP → 丢（不覆盖已收的 UPDATE）
		{Op: "ADD", Key: "称呼", Value: "Dexter", Importance: 7},
		{Op: "ADD", Key: "称呼", Value: "Dex", Importance: 3}, // 同 key 重复 → 保留末个（值+importance）
	}
	out := sanitizeOps(in, existing)
	if len(out) != 4 {
		t.Fatalf("应剩 4 条（重要事/语言/删旧公司/称呼），得 %d: %+v", len(out), out)
	}
	byKey := map[string]memOp{}
	for _, o := range out {
		byKey[o.Key] = o
	}
	if byKey["重要事"].Importance != 10 {
		t.Errorf("重要事 importance 应夹到 10: %+v", byKey["重要事"])
	}
	if byKey["语言"].Op != "UPDATE" || byKey["语言"].Importance != 1 {
		t.Errorf("语言 应为 UPDATE 且 importance 提到 1: %+v", byKey["语言"])
	}
	if byKey["旧公司"].Op != "DELETE" {
		t.Errorf("旧公司 应保留 DELETE: %+v", byKey["旧公司"])
	}
	if byKey["称呼"].Value != "Dex" || byKey["称呼"].Importance != 3 {
		t.Errorf("称呼 应取末个 op（Dex/3）: %+v", byKey["称呼"])
	}
}

func TestParseProfile(t *testing.T) {
	m := parseProfile("- 称呼：Dexter\n- 语言: 中文\n\n- 职业：律师")
	if m["称呼"] != "Dexter" || m["语言"] != "中文" || m["职业"] != "律师" {
		t.Errorf("画像解析错: %v", m)
	}
	if len(parseProfile("")) != 0 {
		t.Error("空画像应得空 map")
	}
}
