package events

import (
	"agent/client/events/opts"
	"agent/defines/derrs"
	"agent/defines/devent/dtype"
	"context"
	"errors"
)

type OnResult func(ctx context.Context, client IClient, eventIn IEvent, eventOut IEvent) error

func ExecuteAndGetData(ctx context.Context, client IClient,
	eventIn IEvent, onResult ...OnResult,
) (data []byte, err error) {
	eventOut, err := client.Execute(ctx, eventIn)
	if err != nil {
		return nil, err
	}
	if len(onResult) > 0 {
		if err = onResult[0](ctx, client, eventIn, eventOut); err != nil {
			return nil, err
		}
	}
	if eventOut != nil {
		data, err := eventOut.Data2()
		if err != nil {
			return nil, err
		}
		if eventOut.Type() == dtype.ResultError {
			return nil, errors.New(string(data))
		}
		return data, nil
	}
	if resp := opts.Response(eventIn); resp != nil {
		if resp.Exist && !resp.CanEmpty {
			return nil, derrs.NewUnknownError(`data is empty`)
		}
	}
	return nil, nil
}

func ExecuteAndGetMetaAndData(ctx context.Context, client IClient,
	eventIn IEvent, onResult ...OnResult,
) (meta map[string]any, data []byte, err error) {
	eventOut, err := client.Execute(ctx, eventIn)
	if err != nil {
		return nil, nil, err
	}
	if len(onResult) > 0 {
		if err = onResult[0](ctx, client, eventIn, eventOut); err != nil {
			return nil, nil, err
		}
	}
	if eventOut != nil {
		data, err = eventOut.Data2()
		return eventOut.Meta(), data, err
	}
	if resp := opts.Response(eventIn); resp != nil {
		if resp.Exist && !resp.CanEmpty {
			return nil, nil, derrs.NewUnknownError(`data is empty`)
		}
	}
	return nil, nil, nil
}
