package automation

import (
	"sync/atomic"
	"time"
)

// SchedulerWorkerSnapshot contains process-local Runtime Worker evidence. It
// never participates in schedule discovery, durable acceptance, or execution.
type SchedulerWorkerSnapshot struct {
	DiscoveryPasses       uint64
	DiscoveryIdle         uint64
	DefinitionsConsidered uint64
	OccurrencesAccepted   uint64
	AcceptanceAttempts    uint64
	AcceptanceEmpty       uint64
	RecoveryScanned       uint64
	RecoveryRecovered     uint64
	ExecutionStarted      uint64
	ExecutionCompleted    uint64
	ExecutionFailed       uint64
	CapacityDeferrals     uint64
	DiscoveryFailures     uint64
	DiscoveryDuration     time.Duration
	RecoveryDuration      time.Duration
	ExecutionDuration     time.Duration
	AcceptanceDuration    time.Duration
}

type schedulerWorkerObservation struct {
	discoveryPasses        atomic.Uint64
	discoveryIdle          atomic.Uint64
	definitionsConsidered  atomic.Uint64
	occurrencesAccepted    atomic.Uint64
	acceptanceAttempts     atomic.Uint64
	acceptanceEmpty        atomic.Uint64
	recoveryScanned        atomic.Uint64
	recoveryRecovered      atomic.Uint64
	executionStarted       atomic.Uint64
	executionCompleted     atomic.Uint64
	executionFailed        atomic.Uint64
	capacityDeferrals      atomic.Uint64
	discoveryFailures      atomic.Uint64
	discoveryDurationNano  atomic.Int64
	recoveryDurationNano   atomic.Int64
	executionDurationNano  atomic.Int64
	acceptanceDurationNano atomic.Int64
}

func (o *schedulerWorkerObservation) snapshot() SchedulerWorkerSnapshot {
	if o == nil {
		return SchedulerWorkerSnapshot{}
	}
	return SchedulerWorkerSnapshot{
		DiscoveryPasses: o.discoveryPasses.Load(), DiscoveryIdle: o.discoveryIdle.Load(),
		DefinitionsConsidered: o.definitionsConsidered.Load(),
		OccurrencesAccepted:   o.occurrencesAccepted.Load(),
		AcceptanceAttempts:    o.acceptanceAttempts.Load(),
		AcceptanceEmpty:       o.acceptanceEmpty.Load(),
		RecoveryScanned:       o.recoveryScanned.Load(), RecoveryRecovered: o.recoveryRecovered.Load(),
		ExecutionStarted: o.executionStarted.Load(), ExecutionCompleted: o.executionCompleted.Load(),
		ExecutionFailed: o.executionFailed.Load(), CapacityDeferrals: o.capacityDeferrals.Load(),
		DiscoveryFailures:  o.discoveryFailures.Load(),
		DiscoveryDuration:  time.Duration(o.discoveryDurationNano.Load()),
		RecoveryDuration:   time.Duration(o.recoveryDurationNano.Load()),
		ExecutionDuration:  time.Duration(o.executionDurationNano.Load()),
		AcceptanceDuration: time.Duration(o.acceptanceDurationNano.Load()),
	}
}

func (s *SchedulerService) WorkerObservationSnapshot() SchedulerWorkerSnapshot {
	if s == nil {
		return SchedulerWorkerSnapshot{}
	}
	return s.workerObservation.snapshot()
}
