package loop_test

import (
	"encoding/json"
	"reflect"
	"testing"

	"github.com/lace-ai/gai/ai"
	"github.com/lace-ai/gai/loop"
)

func TestDecodeToolArgs(t *testing.T) {
	t.Parallel()

	type SampleArgs struct {
		Foo string `json:"foo"`
		Bar int    `json:"bar"`
	}

	ValidArgs := SampleArgs{
		Foo: "hello",
		Bar: 42,
	}

	jsonArgs, err := json.Marshal(ValidArgs)
	if err != nil {
		t.Fatalf("marshal sample args: %v", err)
	}

	req := ai.ToolCall{
		ID:   "call_1",
		Type: "function",
		Name: "test_tool",
	}

	tests := []struct {
		name     string
		input    json.RawMessage
		wantErr  bool
		wantArgs SampleArgs
	}{
		{
			name:     "valid args",
			input:    jsonArgs,
			wantErr:  false,
			wantArgs: ValidArgs,
		},
		{
			name:    "invalid json",
			input:   json.RawMessage(`{"foo": "hello", "bar": }`),
			wantErr: true,
		},
		{
			name:    "invalid Tool Args",
			input:   json.RawMessage(`{"foo": "hello", "bar": "not an int"}`),
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var gotArgs SampleArgs

			tReq := req
			tReq.Args = tt.input
			err := loop.DecodeToolArgs(&tReq, &gotArgs)

			if (err != nil) != tt.wantErr {
				t.Fatalf("DecodeToolArgs() error = %v, wantErr %v", err, tt.wantErr)
			}
			if tt.wantErr {
				return
			}

			if !reflect.DeepEqual(gotArgs, tt.wantArgs) {
				t.Errorf("Decoded args = %#v, want %#v", gotArgs, tt.wantArgs)
			}
		})
	}
}
