package controllogic

import (
	"math"
	"testing"

	"github.com/uopi/uopi/internal/confmgr"
)

func TestFormatAny(t *testing.T) {
	cases := []struct {
		in   any
		want string
	}{
		{3.5, "3.5"},
		{float64(42), "42"},
		{"hello", "hello"},
		{true, "true"},
		{int64(7), "7"},
	}
	for _, c := range cases {
		if got := formatAny(c.in); got != c.want {
			t.Errorf("formatAny(%v) = %q, want %q", c.in, got, c.want)
		}
	}
}

func TestTestThreshold(t *testing.T) {
	cases := []struct {
		val  float64
		op   string
		cmp  float64
		want bool
	}{
		{1, "<", 2, true},
		{3, "<", 2, false},
		{2, ">=", 2, true},
		{1, ">=", 2, false},
		{2, "<=", 2, true},
		{3, "<=", 2, false},
		{2, "==", 2, true},
		{2, "!=", 3, true},
		{5, ">", 2, true},           // default branch
		{1, "", 0, true},            // empty op → ">"
		{math.NaN(), "<", 1, false}, // NaN never satisfies
	}
	for _, c := range cases {
		if got := testThreshold(c.val, c.op, c.cmp); got != c.want {
			t.Errorf("testThreshold(%v,%q,%v) = %v, want %v", c.val, c.op, c.cmp, got, c.want)
		}
	}
}

func TestParseFloat(t *testing.T) {
	cases := []struct {
		in   string
		want float64
	}{
		{"3.14", 3.14},
		{"  10  ", 10},
		{"", 0},
		{"not-a-number", 0},
	}
	for _, c := range cases {
		if got := parseFloat(c.in); got != c.want {
			t.Errorf("parseFloat(%q) = %v, want %v", c.in, got, c.want)
		}
	}
}

func TestCoerceParamValue(t *testing.T) {
	if v := coerceParamValue(confmgr.Parameter{Type: confmgr.TypeInt}, 3.9); v != int64(3) {
		t.Errorf("int coerce = %v, want 3", v)
	}
	if v := coerceParamValue(confmgr.Parameter{Type: confmgr.TypeBool}, 0); v != false {
		t.Errorf("bool 0 = %v, want false", v)
	}
	if v := coerceParamValue(confmgr.Parameter{Type: confmgr.TypeBool}, 1); v != true {
		t.Errorf("bool 1 = %v, want true", v)
	}
	if v := coerceParamValue(confmgr.Parameter{Type: confmgr.TypeString}, 2.5); v != "2.5" {
		t.Errorf("string coerce = %v, want \"2.5\"", v)
	}
	if v := coerceParamValue(confmgr.Parameter{Type: confmgr.TypeFloat}, 1.25); v != 1.25 {
		t.Errorf("float coerce = %v, want 1.25", v)
	}
}

func TestSign(t *testing.T) {
	if sign(5) != 1 || sign(-5) != -1 || sign(0) != 0 {
		t.Errorf("sign mismatch: %d %d %d", sign(5), sign(-5), sign(0))
	}
}
