package main

import (
	
	
	
	
	
	

	
	amhelp 
	am 
	arpc 
	ssrpc 
)

const addr = "localhost:8090"

var ss = states.ExampleStates

func init() {
	// am-dbg is required for debugging, go run it
	// go run github.com/pancsta/asyncmachine-go/tools/cmd/am-dbg@latest
	// amhelp.EnableDebugging(true)
	// amhelp.SetEnvLogLevel(am.LogOps)
}

func main() {
	,  := context.WithCancel(context.Background())
	defer ()

	// handle exit
	 := make(chan os.Signal, 1)
	signal.Notify(, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		<-
		()
	}()

	// worker
	,  := newWorker()
	if  != nil {
		panic()
	}

	// arpc
	,  := newServer(, addr, )
	if  != nil {
		panic()
	}

	// server start
	.Start()
	 = amhelp.WaitForAll(, 3*time.Second,
		.Mach.When1(ssrpc.ServerStates.RpcReady, ))
	if  != nil {
		panic()
	}
	fmt.Printf("Started aRPC server on %s\n", .Addr)

	// wait for a client
	 = amhelp.WaitForAll(, 3*time.Second,
		.Mach.When1(ssrpc.ServerStates.Ready, ))

	// periodically send data to the client
	 := time.NewTicker(3 * time.Second)
	for {
		 := false
		select {
		case <-.C:
			.Add1(ssrpc.WorkerStates.SendPayload, arpc.Pass(&arpc.A{
				Name: "mypayload",
				Payload: &arpc.ArgsPayload{
					Name:   "mypayload",
					Source: "worker1",
					Data:   "Hello aRPC",
				},
			}))
		case <-.Done():
			 = true
		}
		if  {
			break
		}
	}

	fmt.Println("bye")
}

func newWorker( context.Context) (*am.Machine, error) {

	// init
	,  := am.NewCommon(, "worker", states.ExampleSchema, ss.Names(), &workerHandlers{}, nil, nil)
	if  != nil {
		return nil, 
	}
	amhelp.MachDebugEnv()

	return , nil
}

func newServer( context.Context,  string,  *am.Machine) (*arpc.Server, error) {

	// init
	,  := arpc.NewServer(, , .Id(), , nil)
	if  != nil {
		panic()
	}
	amhelp.MachDebugEnv(.Mach)

	// start
	.Start()
	 = amhelp.WaitForAll(, 2*time.Second,
		.Mach.When1(ssrpc.ServerStates.RpcReady, ))
	if  != nil {
		return nil, 
	}

	return , nil
}

type workerHandlers struct {
	*am.ExceptionHandler
}

func ( *workerHandlers) ( *am.Event) {
	fmt.Print("FooState")
}

func ( *workerHandlers) ( *am.Event) {
	fmt.Print("BarState")
}

func ( *workerHandlers) ( *am.Event) {
	fmt.Print("BazState")
}