package opsconsole

import (
	"context"
	"fmt"
	"io"
	"sort"
	"time"

	edgeservice "iop/apps/edge/internal/service"
	iop "iop/proto/gen/iop"
)

func BuildNodeCommandRequest(adapter, targetName, sessionID string, timeoutSec int) (*iop.NodeCommandRequest, string) {
	req := edgeservice.BuildNodeCommandRequest(
		iop.NodeCommandType_NODE_COMMAND_TYPE_CAPABILITIES,
		"caps",
		adapter,
		targetName,
		sessionID,
		timeoutSec,
	)
	return req, req.GetRequestId()
}

func StatusWaitTimeout(req *iop.NodeCommandRequest) time.Duration {
	return edgeservice.StatusWaitTimeout(req)
}

func SendCapabilities(ctx context.Context, edgeSvc *edgeservice.Service, out io.Writer, target *TargetState) error {
	return sendNodeCommandView(ctx, out, target, "capabilities", edgeSvc.Capabilities)
}

func SendTransportStatus(ctx context.Context, edgeSvc *edgeservice.Service, out io.Writer, target *TargetState) error {
	return sendNodeCommandView(ctx, out, target, "transport", edgeSvc.TransportStatus)
}

type nodeCommandFunc func(context.Context, edgeservice.NodeCommandRequestSpec) (edgeservice.NodeCommandView, error)

func sendNodeCommandView(ctx context.Context, out io.Writer, target *TargetState, label string, send nodeCommandFunc) error {
	view, err := send(ctx, edgeservice.NodeCommandRequestSpec{
		NodeRef: target.NodeRef, Adapter: target.Adapter, Target: target.Target,
		SessionID: target.SessionID, TimeoutSec: target.TimeoutSec,
	})
	if err != nil {
		return err
	}
	FormatNodeCommandView(out, label, view)
	return nil
}

func FormatNodeCommandView(out io.Writer, label string, view edgeservice.NodeCommandView) {
	fmt.Fprintf(out, "[%s-%s] adapter=%s target=%s session=%s\n", view.NodeLabel, label, view.Adapter, view.Target, view.SessionID)
	if len(view.Result) == 0 {
		fmt.Fprintf(out, "no %s payload returned\n", label)
		return
	}
	keys := make([]string, 0, len(view.Result))
	for key := range view.Result {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	for _, key := range keys {
		fmt.Fprintf(out, "  %s = %s\n", key, view.Result[key])
	}
}
