// Package engine provides a mode-agnostic scan engine that can be used
// independently of any UI layer. This file defines thread-safe statistics
// tracking using atomic operations.
package engine

import "sync/atomic"

// Stats provides thread-safe counters for engine statistics.
// All operations use atomic primitives, so no mutex is needed.
// Use Snapshot() to get a consistent view of all counters.
type Stats struct {
	// workersActive tracks currently running workers.
	workersActive int64

	// queueSize tracks targets waiting to be scanned.
	queueSize int64

	// inFlight tracks HTTP requests currently in progress.
	inFlight int64

	// totalScanned tracks targets that have completed scanning.
	totalScanned int64

	// totalFound tracks total findings discovered.
	totalFound int64

	// totalErrors tracks total errors encountered.
	totalErrors int64

	// rateLimited tracks 429 responses that triggered rate limiting.
	rateLimited int64
}

// IncrementScanned atomically increments the total scanned counter.
func (s *Stats) IncrementScanned() {
	atomic.AddInt64(&s.totalScanned, 1)
}

// IncrementFound atomically increments the total found counter.
func (s *Stats) IncrementFound() {
	atomic.AddInt64(&s.totalFound, 1)
}

// IncrementErrors atomically increments the total errors counter.
func (s *Stats) IncrementErrors() {
	atomic.AddInt64(&s.totalErrors, 1)
}

// IncrementRateLimited atomically increments the rate limited counter.
func (s *Stats) IncrementRateLimited() {
	atomic.AddInt64(&s.rateLimited, 1)
}

// IncrementInFlight atomically increments the in-flight counter.
func (s *Stats) IncrementInFlight() {
	atomic.AddInt64(&s.inFlight, 1)
}

// DecrementInFlight atomically decrements the in-flight counter.
func (s *Stats) DecrementInFlight() {
	atomic.AddInt64(&s.inFlight, -1)
}

// SetWorkersActive atomically sets the workers active counter.
func (s *Stats) SetWorkersActive(n int64) {
	atomic.StoreInt64(&s.workersActive, n)
}

// SetQueueSize atomically sets the queue size counter.
func (s *Stats) SetQueueSize(n int64) {
	atomic.StoreInt64(&s.queueSize, n)
}

// SetInFlight atomically sets the in-flight counter.
func (s *Stats) SetInFlight(n int64) {
	atomic.StoreInt64(&s.inFlight, n)
}

// Snapshot returns a copy of all statistics values.
// The returned StatsSnapshot provides a consistent point-in-time view
// of all counters without holding any locks.
func (s *Stats) Snapshot() StatsSnapshot {
	return StatsSnapshot{
		WorkersActive: atomic.LoadInt64(&s.workersActive),
		QueueSize:     atomic.LoadInt64(&s.queueSize),
		InFlight:      atomic.LoadInt64(&s.inFlight),
		TotalScanned:  atomic.LoadInt64(&s.totalScanned),
		TotalFound:    atomic.LoadInt64(&s.totalFound),
		TotalErrors:   atomic.LoadInt64(&s.totalErrors),
		RateLimited:   atomic.LoadInt64(&s.rateLimited),
	}
}

// StatsSnapshot is an immutable copy of engine statistics.
// Used for reading stats externally without holding locks.
// All fields are exported for direct access.
type StatsSnapshot struct {
	// WorkersActive is the number of currently running workers.
	WorkersActive int64

	// QueueSize is the number of targets waiting to be scanned.
	QueueSize int64

	// InFlight is the number of HTTP requests currently in progress.
	InFlight int64

	// TotalScanned is the number of targets that have completed scanning.
	TotalScanned int64

	// TotalFound is the total number of findings discovered.
	TotalFound int64

	// TotalErrors is the total number of errors encountered.
	TotalErrors int64

	// RateLimited is the count of 429 responses that triggered rate limiting.
	RateLimited int64
}
