package llm

import "testing"

func TestExtractJSONObject(t *testing.T) {
	tests := []struct {
		name string
		in   string
		want string
	}{
		{"plain", `{"a":1}`, `{"a":1}`},
		{"with prose", "Конечно, вот:\n{\"a\":1}\nготово", `{"a":1}`},
		{"fenced json", "```json\n{\"a\":1}\n```", `{"a":1}`},
		{"fenced bare", "```\n{\"a\":1}\n```", `{"a":1}`},
		{"nested", `{"a":{"b":2},"c":3}`, `{"a":{"b":2},"c":3}`},
		{"brace in string", `{"path":"a{b}c","n":1}`, `{"path":"a{b}c","n":1}`},
		{"escaped quote in string", `{"q":"he said \"hi\" {x}"}`, `{"q":"he said \"hi\" {x}"}`},
		{"trailing after object", `{"a":1} extra {ignored}`, `{"a":1}`},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := ExtractJSONObject(tt.in)
			if err != nil {
				t.Fatalf("ExtractJSONObject(%q): %v", tt.in, err)
			}
			if got != tt.want {
				t.Errorf("ExtractJSONObject(%q) = %q, want %q", tt.in, got, tt.want)
			}
		})
	}
}

func TestExtractJSONObject_Errors(t *testing.T) {
	for _, in := range []string{"", "no json here", "just text", `{"unbalanced":1`} {
		if _, err := ExtractJSONObject(in); err == nil {
			t.Errorf("ExtractJSONObject(%q): want error", in)
		}
	}
}
