// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.

// t_builtin-base_test.go
package expr

import (
	"testing"

	"git.portale-stac.it/go-pkg/expr/types/fract"
	"git.portale-stac.it/go-pkg/expr/types/list"
)

func TestFuncBase(t *testing.T) {
	section := "Builtin-Base"

	inputs := []inputType{
		/*   1 */ {`isNil(nil)`, true, nil},
		/*   2 */ {`v=nil; isNil(v)`, true, nil},
		/*   3 */ {`v=5; isNil(v)`, false, nil},
		/*   4 */ {`int(true)`, int64(1), nil},
		/*   5 */ {`int(false)`, int64(0), nil},
		/*   6 */ {`int(3.1)`, int64(3), nil},
		/*   7 */ {`int(3.9)`, int64(3), nil},
		/*   8 */ {`int("432")`, int64(432), nil},
		/*   9 */ {`int("1.5")`, nil, `strconv.Atoi: parsing "1.5": invalid syntax`},
		/*  10 */ {`int("432", 4)`, nil, `int(): too many params -- expected 1, got 2`},
		/*  11 */ {`int(nil)`, nil, `int(): can't convert nil to int`},
		/*  12 */ {`isInt(2+1)`, true, nil},
		/*  13 */ {`isInt(3.1)`, false, nil},
		/*  14 */ {`isFloat(3.1)`, true, nil},
		/*  15 */ {`isString("3.1")`, true, nil},
		/*  16 */ {`isString("3" + 1)`, true, nil},
		/*  17 */ {`isArray(["3",  1])`, true, nil},
		/*  18 */ {`isDict({"a":"3",  "b":1})`, true, nil},
		/*  19 */ {`isFract(1:3)`, true, nil},
		/*  20 */ {`isFract(3:1)`, false, nil},
		/*  21 */ {`isRational(3:1)`, true, nil},
		/*  22 */ {`fract("2.2(3)")`, fract.NewFraction(67, 30), nil},
		/*  23 */ {`fract("1.21(3)")`, fract.NewFraction(91, 75), nil},
		/*  24 */ {`fract(1.21(3))`, fract.NewFraction(91, 75), nil},
		/*  25 */ {`fract(1.21)`, fract.NewFraction(121, 100), nil},
		/*  26 */ {`float(2)`, float64(2), nil},
		/*  27 */ {`float(2.0)`, float64(2), nil},
		/*  28 */ {`float("2.0")`, float64(2), nil},
		/*  29 */ {`float(true)`, float64(1), nil},
		/*  30 */ {`float(true")`, nil, "[1:13] expected one of `,`, `)`, got `\"`"},
		/*  31 */ {`float()`, nil, `float(): too few params -- expected 1, got 0`},
		/*  32 */ {`float(1,2,3)`, nil, `float(): too many params -- expected 1, got 3`},
		/*  33 */ {`isBool(false)`, true, nil},
		/*  34 */ {`fract(1:2)`, fract.NewFraction(1, 2), nil},
		/*  35 */ {`fract(12,2)`, fract.NewFraction(6, 1), nil},
		/*  36 */ {`bool(2)`, true, nil},
		/*  37 */ {`bool(1:2)`, true, nil},
		/*  38 */ {`bool(1.0)`, true, nil},
		/*  39 */ {`bool("1")`, true, nil},
		/*  40 */ {`bool(false)`, false, nil},
		/*  41 */ {`bool([1])`, true, nil},
		/*  42 */ {`bool([])`, false, nil},
		/*  43 */ {`bool({})`, false, nil},
		/*  44 */ {`bool({1:"one"})`, true, nil},
		/*  45 */ {`float(false)`, float64(0), nil},
		/*  46 */ {`float(1:2)`, float64(0.5), nil},
		/*  47 */ {`float([1])`, nil, `float(): can't convert array to float`},
		/*  48 */ {`eval("a=3"); a`, int64(3), nil},
		/*  49 */ {`int(5:2)`, int64(2), nil},

		// /*  45 */ {`string([1])`, nil, `string(): can't convert list to string`},
	}

	t.Setenv("EXPR_PATH", ".")

	// runTestSuiteSpec(t, section, inputs, 49)
	RunTestSuite(t, section, inputs)
}

func TestFuncBaseString(t *testing.T) {
	section := "Builtin-Base-String"

	inputs := []inputType{
		/*   1 */ {`string(3)`, "3", nil},
		/*   2 */ {`string(3.5)`, "3.5", nil},
		/*   3 */ {`string(true)`, "true", nil},
		/*   4 */ {`string(false)`, "false", nil},
		/*   5 */ {`string("123")`, "123", nil},
		/*   6 */ {`string(1:2)`, "1:2", nil},
	}

	// t.Setenv("EXPR_PATH", ".")

	// runTestSuiteSpec(t, section, inputs, 49)
	RunTestSuite(t, section, inputs)
}

func TestFuncBaseFraction(t *testing.T) {
	section := "Builtin-Base-Fraction"

	inputs := []inputType{
		/*   1 */ {`fract(-0.5)`, fract.NewFraction(-1, 2), nil},
		/*   2 */ {`fract("")`, (*fract.FractionType)(nil), `bad syntax`},
		/*   3 */ {`fract("-1")`, fract.NewFraction(-1, 1), nil},
		/*   4 */ {`fract("+1")`, fract.NewFraction(1, 1), nil},
		/*   5 */ {`fract("1a")`, (*fract.FractionType)(nil), `strconv.ParseInt: parsing "1a": invalid syntax`},
		/*   6 */ {`fract(1,0)`, nil, `fract(): division by zero`},
		/*   7 */ {`fract(5, "1")`, nil, `fract(): expected integer, got string ("1")`},
		/*   8 */ {`fract(true)`, fract.NewFraction(1, 1), nil},
		/*   9 */ {`fract(false)`, fract.NewFraction(0, 1), nil},
		/*  10 */ {`1.2(3)`, fract.NewFraction(37, 30), nil},
	}

	// t.Setenv("EXPR_PATH", ".")

	// RunTestSuiteSpec(t, section, inputs, 10)
	RunTestSuite(t, section, inputs)
}

func TestFuncBaseOthers(t *testing.T) {
	section := "Builtin-Base-Others"

	inputs := []inputType{
		/*   1 */ {`set("a", 3); a`, int64(3), nil},
		/*   2 */ {`set(true, 3)`, nil, `set(): the "name" parameter must be a string, got a bool (true)`},
		/*   3 */ {`seq(1,2,3)`, list.NewLinkedListA(int64(1), int64(2), int64(3)), nil},
		// /*   4 */ {`seq(1,2,4)`, kern.NewLinkedListA(int64(1), int64(2), int64(3)), nil},
	}

	// RunTestSuiteSpec(t, section, inputs, 3)
	RunTestSuite(t, section, inputs)
}
