package service

import (
	"context"
	"fmt"
	"time"

	"helmet/pkg/client"
	"helmet/pkg/mlbctl"

	"github.com/spf13/cobra"
	"sigs.k8s.io/yaml"
)

type Tool struct {
	cmd                *cobra.Command
	serviceHelloParams ServiceHelloParams
}

func NewTool() *Tool {
	tool := &Tool{}
	tool.cmd = &cobra.Command{
		Use:   "service",
		Short: "Service operation",
	}
	serviceHelloCmd := &cobra.Command{
		Use:   "hello",
		Args:  cobra.ExactArgs(1),
		Short: "Send and receive hello",
		Run:   tool.ServiceHello,
	}
	tool.cmd.AddCommand(serviceHelloCmd)
	return tool
}

func (tool *Tool) GetCmd() *cobra.Command {
	return tool.cmd
}

type ServiceHelloParams struct {
	Hostname string
}
type ServiceHelloResult struct {
	Message string `json:"message,omitempty"`
}

func (tool *Tool) ServiceHello(cmd *cobra.Command, args []string) {
	tool.serviceHelloParams.Hostname = args[0]
	res, err := tool.serviceHello(&tool.serviceHelloParams)
	printResponse(res, err)
}

func (tool *Tool) serviceHello(params *ServiceHelloParams) (*ServiceHelloResult, error) {
	var err error
	res := &ServiceHelloResult{}
	ref, err := client.NewReferer(params.Hostname)
	if err != nil {
		return res, err
	}
	authCred := client.NewAuthCredential(ref.Userinfo())
	conn, cli, err := client.NewClient(ref.Hostinfo(), authCred)
	if err != nil {
		return res, err
	}
	defer conn.Close()
	ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
	opReq := &mlbctl.GetHelloParams{}
	opRes, err := cli.GetHello(ctx, opReq)
	if err != nil {
		return res, err
	}
	res.Message = opRes.Message
	return res, err
}

func printResponse(res any, err error) {
	type Response struct {
		Error   bool   `json:"error"             json:"error"`
		Message string `json:"message,omitempty" json:"message,omitempty"`
		Result  any    `json:"result,omitempty"  json:"result,omitempty"`
	}
	resp := Response{}
	if err != nil {
		resp.Error = true
		resp.Message = err.Error()
	} else {
		resp.Result = res
	}
	respBytes, _ := yaml.Marshal(resp)
	fmt.Printf("---\n%s\n", string(respBytes))
}
