package supervisor

import (
	
	
)

// supervisorInterrupter manages the interruption state between
// [flaky.Executor], [process.Runner] and [process.Callback].
type supervisorInterrupter struct {
	done   chan struct{}
	cancel context.CancelFunc

	stopMu  sync.Mutex
	stopped bool
	running bool
}

// Interrupt signals the supervisor to stop execution.
func ( *supervisorInterrupter) () {
	.stopMu.Lock()
	defer .stopMu.Unlock()

	if .stopped {
		return
	}
	.stopped = true

	if .running {
		close(.done)
	} else {
		.cancel()
	}
}

// shouldStopBeforeRun checks if an interrupt was requested before runner
// execution starts. It sets the running flag to true and returns whether
// execution should be stopped. It panics if the executor wasn’t properly
// interrupted after a stop was requested.
func ( *supervisorInterrupter) () bool {
	.stopMu.Lock()
	defer .stopMu.Unlock()
	if .stopped && .running {
		panic("supervisor: executor was not interrupted")
	}
	.running = true
	return .stopped
}

// afterRunner handles cleanup after the runner completes execution. It cancels the
// callback context if an interrupt was requested during execution.
func ( *supervisorInterrupter) () {
	.stopMu.Lock()
	defer .stopMu.Unlock()

	// Stop executor after runner returns. Note that we do not unset running
	// flag to handle faulty executors (see panic in shouldStopBeforeRun).
	if .stopped {
		.cancel()
		return
	}

	.running = false
}