package flow

import (
	"errors"
	"fmt"

	"go.starlark.net/starlark"
)

const (
	localOnEventState = "localOnEventState"
	onEventBuiltin    = "on_event"
)

type eventHandler struct {
	handler *starlark.Function
	// a string or a function to construct the workflow ID.
	workflowID starlark.Value
}

type onEventState struct {
	handlers map[string][]eventHandler
}

func onEventBuiltinFunc(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	if len(args) > 0 {
		return nil, fmt.Errorf("%s: unexpected positional arguments", fn.Name())
	}
	var (
		eventType  string
		handler    *starlark.Function
		workflowID starlark.Value = starlark.String("")
	)
	err := starlark.UnpackArgs(fn.Name(), nil, kwargs,
		"type", &eventType,
		"handler", &handler,
		"workflow_id?", &workflowID,
	)
	if err != nil {
		return nil, err
	}
	if handler.NumParams() > 2 {
		return nil, fmt.Errorf("%s: too many parameters, must be 2 or fewer", fn.Name())
	}
	s, ok := thread.Local(localOnEventState).(*onEventState)
	if !ok {
		return nil, errors.New("internal error: local onEventState not found")
	}
	s.handlers[eventType] = append(s.handlers[eventType], eventHandler{
		handler:    handler,
		workflowID: workflowID,
	})

	return starlark.None, nil
}
