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

// builtin-fmt.go
package expr

import (
	"fmt"
	"io"
	"os"

	"git.portale-stac.it/go-pkg/expr/kern"
)

func getStdout(ctx kern.ExprContext) io.Writer {
	var w io.Writer
	if wany, exists := ctx.GetVar(kern.ControlStdout); exists && wany != nil {
		w, _ = wany.(io.Writer)
	}
	if w == nil {
		w = os.Stdout
	}
	return w
}

func printFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
	var n int = 0
	if v, exists := args[kern.ParamItem]; exists && v != nil {
		argv := v.([]any)
		n, err = fmt.Fprint(getStdout(ctx), argv...)
	}
	result = int64(n)
	return
}

func printLnFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
	var n int = 0
	if v, exists := args[kern.ParamItem]; exists && v != nil {
		argv := v.([]any)
		n, err = fmt.Fprintln(getStdout(ctx), argv...)
	} else {
		n, err = fmt.Fprintln(getStdout(ctx))
	}
	result = int64(n)
	return
}

func ImportFmtFuncs(ctx kern.ExprContext) {
	ctx.RegisterFunc("print", kern.NewGolangFunctor(printFunc), kern.TypeInt, []kern.ExprFuncParam{
		kern.NewFuncParamFlag(kern.ParamItem, kern.PfRepeat),
	})
	ctx.RegisterFunc("println", kern.NewGolangFunctor(printLnFunc), kern.TypeInt, []kern.ExprFuncParam{
		kern.NewFuncParamFlag(kern.ParamItem, kern.PfRepeat),
	})
}

func init() {
	RegisterBuiltinModule("fmt", ImportFmtFuncs, "String and console formatting functions")
}
