package node

import (
	"context"
	"fmt"

	"go.uber.org/zap"

	"iop/apps/node/internal/runtime"
	"iop/apps/node/internal/transport"
	iop "iop/proto/gen/iop"
)

// OnCancel cancels a running execution or terminates an adapter session.
func (n *Node) OnCancel(_ context.Context, _ *transport.Session, req *iop.CancelRequest) error {
	n.logger.Info("cancel request", zap.String("run_id", req.GetRunId()), zap.String("action", req.GetAction().String()))

	switch cancelActionFromProto(req.GetAction()) {
	case runtime.CancelActionTerminateSession:
		adapter, err := n.router.LookupAdapter(req.GetAdapter())
		if err != nil {
			return fmt.Errorf("node: %w", err)
		}
		terminator, ok := adapter.(runtime.SessionTerminator)
		if !ok {
			return fmt.Errorf("node: adapter %q does not support session termination", req.GetAdapter())
		}
		return terminator.TerminateSession(context.Background(), req.GetTarget(), normalizeSessionID(req.GetSessionId()))
	default:
		n.runs.cancelRun(req.GetRunId())
		return nil
	}
}
