package main

import (
	
	
	

	
	

	
	
	amhelp 
	am 
	arpc 
	ssrpc 
)

var ss = states.DaemonStates

type Args struct {
	Foo1     bool          `arg:"--foo-1" help:"Foo help"`
	Bar2     bool          `arg:"--bar-2" help:"Bar help"`
	Addr     string        `default:"localhost:8090"`
	Duration time.Duration `arg:"-d,--duration" default:"3s" help:"Duration of the op"`
	Debug    bool          `default:"true" help:"Enable debugging for asyncmachine"`
}

// TODO subcommand "daemon" which fwd args to the daemon

type cli struct {
	*am.ExceptionHandler

	Mach      *am.Machine
	DaemonRpc *arpc.Client
	Args      *Args
}

var args Args

func main() {
	 := arg.MustParse(&args)
	 := context.Background()
	,  := newCli(, &args)
	if  != nil {
		.Fail(.Error())
	}
	 := .DaemonRpc.NetMach

	if args.Foo1 {
		.Add1(ss.OpFoo1, types.PassRpc(&types.ARpc{
			Duration: args.Duration,
		}))
	} else if args.Bar2 {
		.Add1(ss.OpBar2, types.PassRpc(&types.ARpc{
			Duration: args.Duration,
		}))
	} else {
		.Fail("no flag")
	}

	 = amhelp.WaitForAll(, 5*time.Second,
		.Mach.When1(ssrpc.ConsumerStates.WorkerPayload, nil))
	if  != nil {
		.Fail(.Error())
	}
}

// newCli creates a new CLI with a state machine.
func newCli( context.Context,  *Args) (*cli, error) {
	if .Debug {
		fmt.Printf("debugging enabled\n")
		// load .env
		_ = godotenv.Load()
	}

	// init cli
	 := am.New(, ssrpc.ConsumerSchema, nil)
	 := .BindHandlers(&cli{})
	if  != nil {
		return nil, 
	}

	// init aRPC client
	,  := newClient(, .Addr, , states.DaemonSchema)
	if  != nil {
		return nil, 
	}

	// connect
	.Start()
	 = amhelp.WaitForAll(, 3*time.Second,
		.Mach.When1(ssrpc.ClientStates.Ready, ))
	fmt.Printf("Connected to aRPC %s\n", .Addr)

	return &cli{
		Mach:      ,
		DaemonRpc: ,
		Args:      ,
	}, nil
}

func newClient(
	 context.Context,  string,  *am.Machine,  am.Schema,
) (*arpc.Client, error) {

	// init
	 := "cli-" + time.Now().Format(time.RFC3339Nano)
	,  := arpc.NewClient(, , , , &arpc.ClientOpts{
		Consumer: ,
	})
	if  != nil {
		return nil, 
	}
	amhelp.MachDebugEnv(.Mach)

	return , nil
}

func ( *cli) ( *am.Event) {
	.Machine().Remove1(ssrpc.ConsumerStates.WorkerPayload, nil)

	 := arpc.ParseArgs(.Args)
	println("Payload: " + .Payload.Data.(string))
}