package main

import (
	
	
	

	
	
	am 
	
	ss 
	
	
)

var (
	dataFile       = "assets/asyncmachine-go/am-dbg-exports/pubsub-sim.gob.br"
	logLevel       = am.LogOps
	filterLogLevel = am.LogChanges
	startupMachine = "sim-p1"
	startupTx      = 27
	initialView    = "matrix"
	playInterval   = 200 * time.Millisecond
	debugAddr      = ""
	// debugAddr  = "localhost:6831"
	stateNames = am.S{
		"Start",
		"IsDHT",
		"Ready",
		"IdentityReady",
		"GenIdentity",
		"BootstrapsConnected",
		"EventHostConnected",
		"Connected",
		"Connecting",
		"Disconnecting",
		"JoiningTopic",
		"TopicJoined",
		"LeavingTopic",
		"TopicLeft",
		"SendingMsgs",
		"MsgsSent",
		"FwdToSim",
		am.StateException,
	}
)

func main() {
	 := types.RootCmd(cliRun)
	 := .Execute()
	if  != nil {
		panic()
	}
}

func cliRun( *cobra.Command,  []string,  types.Params) {

	// ctx
	 := context.Background()

	// overwrite params
	.LogLevel = logLevel
	.ImportData = dataFile
	.DebugAddr = debugAddr

	// init the debugger
	,  := debugger.New(, debugger.Opts{
		Filters: &debugger.OptsFilters{
			LogLevel: filterLogLevel,
		},
		ImportData:      .ImportData,
		DbgLogLevel:     .LogLevel,
		DbgLogger:       types.GetLogger(&, ""),
		AddrRpc:         .ListenAddr,
		EnableMouse:     .EnableMouse,
		EnableClipboard: .EnableClipboard,
		Version:         utils.GetVersion(),
		Id:              "video",
		MaxMemMb:        1000,
	})
	if  != nil {
		panic()
	}
	helpers.MachDebug(.Mach, debugAddr, logLevel, false,
		&am.SemConfig{Full: true})

	.Start(startupMachine, startupTx, initialView, "")
	go render()

	select {
	case <-.Mach.WhenDisposed():
	case <-.Mach.WhenNot1(ss.Start, nil):
	}

	.Dispose()
}

func render( *debugger.Debugger) {
	// SkipStart() // TODO

	 := .Mach
	// ctx := mach.Ctx
	<-.When1(ss.Ready, nil)
	time.Sleep(100 * time.Millisecond)

	// play
	goFwd(, 20)

	// goFwd(mach, 1)
	.Add1(ss.TreeMatrixView, nil)
	goFwd(, 14)

	// play steps
	.Add1(ss.TimelineStepsFocused, nil)
	 := .NextTx()
	goFwdSteps(, len(.Steps)+1)

	// play steps with moving selection
	 = .NextTx()
	 := -1
	for  := 0;  < len(.Steps); ++ {
		 = ( + 1) % len(stateNames)
		.Add1(ss.StateNameSelected, am.A{"state": stateNames[]})

		goFwdSteps(, 1)
	}

	// keep the highlight 1 frame longer
	++

	// play steps back with moving selection
	for  := 0;  < len(.Steps); ++ {
		 = ( - 1) % len(stateNames)
		 = int(math.Max(0, float64()))
		if  > -1 {
			.Add1(ss.StateNameSelected, am.A{"state": stateNames[]})
		} else {
			.Remove1(ss.StateNameSelected, nil)
		}

		goBackSteps(, 1)
	}

	.Remove1(ss.StateNameSelected, nil)
	.Add(am.S{ss.TreeMatrixView, ss.MatrixRain}, nil)
	.Add1(ss.ClientListFocused, nil)
	goBack(, 14)

	// go back with clean UI
	.SetFilterLogLevel(am.LogOps)
	.Add1(ss.TreeLogView, nil)
	goBack(, 14)

	SkipEnd() // TODO
	.Add1(ss.LogTimestamps, nil)
	.SetFilterLogLevel(am.LogChanges)
	// TODO via state handlers, pass focused filter
	.Add1(ss.Toolbar1Focused, am.A{"filter": debugger.ToolLogTimestamps})
	// dbg.HProcessFilterChange(context.TODO(), false)
	goBack(, 1)

	// end screen
	time.Sleep(3 * time.Second)
	.Dispose()
}

func () {
	playInterval = 200 * time.Millisecond
}

func () {
	playInterval = 10 * time.Millisecond
}

func goFwd( *am.Machine,  int) {
	for  := 0;  < ; ++ {
		.Add1(ss.Fwd, nil)
		time.Sleep(playInterval)
	}
}

func goBack( *am.Machine,  int) {
	for  := 0;  < ; ++ {
		.Add1(ss.Back, nil)
		time.Sleep(playInterval)
	}
}

func goFwdSteps( *am.Machine,  int) {
	for  := 0;  < ; ++ {
		.Add1(ss.FwdStep, nil)
		time.Sleep(playInterval)
	}
}

func goBackSteps( *am.Machine,  int) {
	for  := 0;  < ; ++ {
		.Add1(ss.BackStep, nil)
		time.Sleep(playInterval)
	}
}