package prediction

import (
	"encoding/json"
	"testing"
)

func TestResolveSeedNegativeInt(t *testing.T) {
	got := resolveSeed(-1)
	n, ok := got.(int)
	if !ok || n < 0 {
		t.Fatalf("expected non-negative int, got %v", got)
	}
}

func TestResolveSeedNegativeFloat64(t *testing.T) {
	got := resolveSeed(float64(-1))
	n, ok := got.(int)
	if !ok || n < 0 {
		t.Fatalf("expected non-negative int from float64 -1, got %v", got)
	}
}

func TestResolveSeedExplicit(t *testing.T) {
	if got := resolveSeed(42); got != 42 {
		t.Fatalf("expected 42, got %v", got)
	}
}

func TestBuildPromptSanitizesUnboundKSamplerSeed(t *testing.T) {
	workflow := map[string]any{
		"17": map[string]any{
			"class_type": "KSampler",
			"inputs": map[string]any{
				"seed":  float64(-1),
				"steps": 20,
			},
		},
	}
	raw, _ := json.Marshal(workflow)
	prompt, err := BuildPrompt(string(raw), InputBinding{}, map[string]any{})
	if err != nil {
		t.Fatal(err)
	}
	node := prompt["17"].(map[string]any)
	inputs := node["inputs"].(map[string]any)
	seed, ok := inputs["seed"].(int)
	if !ok || seed < 0 {
		t.Fatalf("expected sanitized seed, got %v", inputs["seed"])
	}
}

func TestBuildPromptSeedBindingAfterCloneMap(t *testing.T) {
	workflow := map[string]any{
		"17": map[string]any{
			"class_type": "KSampler",
			"inputs":     map[string]any{"seed": 0},
		},
	}
	raw, _ := json.Marshal(workflow)
	binding := InputBinding{
		"seed": {Node: "17", Field: "seed"},
	}
	// cloneMap round-trip produces float64, as in execute().
	input := cloneMap(map[string]any{"seed": -1})
	prompt, err := BuildPrompt(string(raw), binding, input)
	if err != nil {
		t.Fatal(err)
	}
	inputs := prompt["17"].(map[string]any)["inputs"].(map[string]any)
	seed, ok := inputs["seed"].(int)
	if !ok || seed < 0 {
		t.Fatalf("expected non-negative seed after binding, got %v", inputs["seed"])
	}
}
