package filters

import (
	"testing"

	"go.starlark.net/starlark"
)

func TestParseStarlarkMessages_None(t *testing.T) {
	msgs, err := parseStarlarkMessages(starlark.None)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if msgs != nil {
		t.Fatalf("expected nil, got %d messages", len(msgs))
	}
}

func TestParseStarlarkMessages_Nil(t *testing.T) {
	msgs, err := parseStarlarkMessages(nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if msgs != nil {
		t.Fatalf("expected nil, got %d messages", len(msgs))
	}
}

func TestParseStarlarkMessages_EmptyList(t *testing.T) {
	msgs, err := parseStarlarkMessages(starlark.NewList(nil))
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if msgs != nil {
		t.Fatalf("expected nil, got %d messages", len(msgs))
	}
}

func TestParseStarlarkMessages_SingleMessage(t *testing.T) {
	d := starlark.NewDict(2)
	d.SetKey(starlark.String("role"), starlark.String("system"))
	d.SetKey(starlark.String("content"), starlark.String("injected context"))
	list := starlark.NewList([]starlark.Value{d})

	msgs, err := parseStarlarkMessages(list)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(msgs) != 1 {
		t.Fatalf("expected 1 message, got %d", len(msgs))
	}
	if msgs[0].Role != "system" {
		t.Fatalf("expected role 'system', got %q", msgs[0].Role)
	}
	if msgs[0].Content != "injected context" {
		t.Fatalf("expected content 'injected context', got %q", msgs[0].Content)
	}
}

func TestParseStarlarkMessages_MultipleMessages(t *testing.T) {
	d1 := starlark.NewDict(2)
	d1.SetKey(starlark.String("role"), starlark.String("system"))
	d1.SetKey(starlark.String("content"), starlark.String("first"))

	d2 := starlark.NewDict(2)
	d2.SetKey(starlark.String("role"), starlark.String("system"))
	d2.SetKey(starlark.String("content"), starlark.String("second"))

	list := starlark.NewList([]starlark.Value{d1, d2})

	msgs, err := parseStarlarkMessages(list)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(msgs) != 2 {
		t.Fatalf("expected 2 messages, got %d", len(msgs))
	}
	if msgs[0].Content != "first" || msgs[1].Content != "second" {
		t.Fatalf("wrong content: %q, %q", msgs[0].Content, msgs[1].Content)
	}
}

func TestParseStarlarkMessages_MissingRole(t *testing.T) {
	d := starlark.NewDict(1)
	d.SetKey(starlark.String("content"), starlark.String("no role"))
	list := starlark.NewList([]starlark.Value{d})

	_, err := parseStarlarkMessages(list)
	if err == nil {
		t.Fatal("expected error for missing role")
	}
}

func TestParseStarlarkMessages_MissingContent(t *testing.T) {
	d := starlark.NewDict(1)
	d.SetKey(starlark.String("role"), starlark.String("system"))
	list := starlark.NewList([]starlark.Value{d})

	_, err := parseStarlarkMessages(list)
	if err == nil {
		t.Fatal("expected error for missing content")
	}
}

func TestParseStarlarkMessages_WrongType(t *testing.T) {
	_, err := parseStarlarkMessages(starlark.String("not a list"))
	if err == nil {
		t.Fatal("expected error for wrong type")
	}
}

func TestParseStarlarkMessages_NonDictInList(t *testing.T) {
	list := starlark.NewList([]starlark.Value{starlark.String("not a dict")})

	_, err := parseStarlarkMessages(list)
	if err == nil {
		t.Fatal("expected error for non-dict in list")
	}
}
